Skip to content

Commit 18ba1ff

Browse files
authoredJun 24, 2021
Make sure that line number is set correctly for call to __exit__ when handling exception in body of a with statement. (GH-26890)
1 parent 599c070 commit 18ba1ff

File tree

5 files changed

+4522
-4505
lines changed

5 files changed

+4522
-4505
lines changed
 

‎Lib/test/test_exceptions.py

+24-7
Original file line numberDiff line numberDiff line change
@@ -2160,18 +2160,23 @@ def test_incorrect_constructor(self):
21602160

21612161
class PEP626Tests(unittest.TestCase):
21622162

2163-
def lineno_after_raise(self, f, line):
2163+
def lineno_after_raise(self, f, *expected):
21642164
try:
21652165
f()
21662166
except Exception as ex:
21672167
t = ex.__traceback__
2168-
while t.tb_next:
2169-
t = t.tb_next
2168+
else:
2169+
self.fail("No exception raised")
2170+
lines = []
2171+
t = t.tb_next # Skip this function
2172+
while t:
21702173
frame = t.tb_frame
2171-
if line is None:
2172-
self.assertEqual(frame.f_lineno, line)
2173-
else:
2174-
self.assertEqual(frame.f_lineno-frame.f_code.co_firstlineno, line)
2174+
lines.append(
2175+
None if frame.f_lineno is None else
2176+
frame.f_lineno-frame.f_code.co_firstlineno
2177+
)
2178+
t = t.tb_next
2179+
self.assertEqual(tuple(lines), expected)
21752180

21762181
def test_lineno_after_raise_simple(self):
21772182
def simple():
@@ -2250,5 +2255,17 @@ def f():
22502255
f.__code__ = f.__code__.replace(co_linetable=b'\x04\x80\xff\x80')
22512256
self.lineno_after_raise(f, None)
22522257

2258+
def test_lineno_after_raise_in_with_exit(self):
2259+
class ExitFails:
2260+
def __enter__(self):
2261+
return self
2262+
def __exit__(self, *args):
2263+
raise ValueError
2264+
2265+
def after_with():
2266+
with ExitFails():
2267+
1/0
2268+
self.lineno_after_raise(after_with, 1, 1)
2269+
22532270
if __name__ == '__main__':
22542271
unittest.main()

‎Python/compile.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -5053,6 +5053,7 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
50535053

50545054
static int
50555055
compiler_with_except_finish(struct compiler *c, basicblock * cleanup) {
5056+
c->u->u_lineno = -1;
50565057
basicblock *exit;
50575058
exit = compiler_new_block(c);
50585059
if (exit == NULL)
@@ -5168,7 +5169,6 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
51685169

51695170
/* For exceptional outcome: */
51705171
compiler_use_next_block(c, final);
5171-
c->u->u_lineno = -1;
51725172

51735173
ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
51745174
ADDOP(c, PUSH_EXC_INFO);
@@ -5265,7 +5265,6 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
52655265

52665266
/* For exceptional outcome: */
52675267
compiler_use_next_block(c, final);
5268-
c->u->u_lineno = -1;
52695268

52705269
ADDOP_JUMP(c, SETUP_CLEANUP, cleanup);
52715270
ADDOP(c, PUSH_EXC_INFO);

‎Python/importlib.h

+1,729-1,729
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Python/importlib_external.h

+2,436-2,436
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Python/importlib_zipimport.h

+332-331
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.