Skip to content

Commit 148a1d0

Browse files
authored
Spill the old exception in iterators with excepts (mypyc/mypyc#683)
1 parent 56ed494 commit 148a1d0

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

mypyc/genops.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -953,12 +953,12 @@ class ExceptNonlocalControl(CleanupNonlocalControl):
953953
Just makes sure that sys.exc_info always gets restored when we leave.
954954
This is super annoying.
955955
"""
956-
def __init__(self, outer: NonlocalControl, saved: Value) -> None:
956+
def __init__(self, outer: NonlocalControl, saved: Union[Value, AssignmentTarget]) -> None:
957957
super().__init__(outer)
958958
self.saved = saved
959959

960960
def gen_cleanup(self, builder: 'IRBuilder', line: int) -> None:
961-
builder.primitive_op(restore_exc_info_op, [self.saved], line)
961+
builder.primitive_op(restore_exc_info_op, [builder.read(self.saved)], line)
962962

963963

964964
class FinallyNonlocalControl(CleanupNonlocalControl):
@@ -3550,7 +3550,7 @@ def visit_try_except(self,
35503550
# exception is raised, based on the exception in exc_info.
35513551
self.error_handlers.append(double_except_block)
35523552
self.activate_block(except_entry)
3553-
old_exc = self.primitive_op(error_catch_op, [], line)
3553+
old_exc = self.maybe_spill(self.primitive_op(error_catch_op, [], line))
35543554
# Compile the except blocks with the nonlocal control flow overridden to clear exc_info
35553555
self.nonlocal_control.append(
35563556
ExceptNonlocalControl(self.nonlocal_control[-1], old_exc))
@@ -3583,14 +3583,14 @@ def visit_try_except(self,
35833583
# restore the saved exc_info information and continue propagating
35843584
# the exception if it exists.
35853585
self.activate_block(cleanup_block)
3586-
self.primitive_op(restore_exc_info_op, [old_exc], line)
3586+
self.primitive_op(restore_exc_info_op, [self.read(old_exc)], line)
35873587
self.goto(exit_block)
35883588

35893589
# Cleanup for if we leave except through a raised exception:
35903590
# restore the saved exc_info information and continue propagating
35913591
# the exception.
35923592
self.activate_block(double_except_block)
3593-
self.primitive_op(restore_exc_info_op, [old_exc], line)
3593+
self.primitive_op(restore_exc_info_op, [self.read(old_exc)], line)
35943594
self.primitive_op(keep_propagating_op, [], NO_TRACEBACK_LINE_NO)
35953595
self.add(Unreachable())
35963596

test-data/run.test

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ Traceback (most recent call last):
11721172
Exception
11731173

11741174
[case testTryExcept]
1175-
from typing import Any
1175+
from typing import Any, Iterator
11761176
import wrapsys
11771177
def g(b: bool) -> None:
11781178
try:
@@ -1250,6 +1250,12 @@ def m(x: object) -> int:
12501250
return -1
12511251
return st + 1
12521252

1253+
def iter_exception() -> Iterator[str]:
1254+
try:
1255+
r(0)
1256+
except KeyError as e:
1257+
yield 'lol'
1258+
12531259
[file wrapsys.py]
12541260
# This is a gross hack around some limitations of the test system/mypyc.
12551261
from typing import Any
@@ -1258,9 +1264,9 @@ def exc_info() -> Any:
12581264
return sys.exc_info() # type: ignore
12591265

12601266
[file driver.py]
1261-
import traceback
1262-
import sys
1263-
from native import g, f, h, i, j, k, l, m
1267+
import sys, traceback
1268+
from native import g, f, h, i, j, k, l, m, iter_exception
1269+
from testutil import assertRaises
12641270
print("== i ==")
12651271
try:
12661272
i()
@@ -1297,6 +1303,10 @@ print("== l ==")
12971303
l()
12981304

12991305
m('lol')
1306+
1307+
with assertRaises(IndexError):
1308+
list(iter_exception())
1309+
13001310
[out]
13011311
== i ==
13021312
<class 'IndexError'>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy