From 4a54074a0f5579d417445ec28427cd0ed5aa01f4 Mon Sep 17 00:00:00 2001 From: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Date: Thu, 14 Sep 2023 17:06:08 +0100 Subject: [PATCH] gh-105658: fix excess trace events for except block ending with a conditional block (#109384) --- Lib/test/test_dis.py | 12 ++++--- Lib/test/test_sys_settrace.py | 31 ++++++++++++++++++- ...-09-13-19-16-51.gh-issue-105658.z2nR2u.rst | 2 ++ Python/compile.c | 16 ++-------- 4 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 568200c9c86c7e..d104e5dd904999 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -642,7 +642,8 @@ def _tryfinallyconst(b): CALL 0 POP_TOP RERAISE 0 - >> COPY 3 + +None >> COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -674,7 +675,8 @@ def _tryfinallyconst(b): CALL 0 POP_TOP RERAISE 0 - >> COPY 3 + +None >> COPY 3 POP_EXCEPT RERAISE 1 ExceptionTable: @@ -1822,9 +1824,9 @@ def _prepare_test_cases(): Instruction(opname='CALL', opcode=53, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='POP_TOP', opcode=32, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None), Instruction(opname='RERAISE', opcode=102, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=28, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=61, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=True, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=31, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=102, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 369a276ac33a12..f02169602e4925 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -929,6 +929,35 @@ def func(): (6, 'line'), (6, 'return')]) + def test_finally_with_conditional(self): + + # See gh-105658 + condition = True + def func(): + try: + try: + raise Exception + finally: + if condition: + result = 1 + result = 2 + except: + result = 3 + return result + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (5, 'line'), + (6, 'line'), + (8, 'line'), + (9, 'line'), + (10, 'line'), + (10, 'return')]) + def test_break_to_continue1(self): def func(): @@ -2123,7 +2152,7 @@ def test_jump_in_nested_finally_3(output): output.append(11) output.append(12) - @jump_test(5, 11, [2, 4], (ValueError, 'exception')) + @jump_test(5, 11, [2, 4], (ValueError, 'comes after the current code block')) def test_no_jump_over_return_try_finally_in_finally_block(output): try: output.append(2) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst new file mode 100644 index 00000000000000..e95f5b84e8e187 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-09-13-19-16-51.gh-issue-105658.z2nR2u.rst @@ -0,0 +1,2 @@ +Fix bug where the line trace of an except block ending with a conditional +includes an excess event with the line of the conditional expression. diff --git a/Python/compile.c b/Python/compile.c index b05c1ad96be803..1d9ae626677310 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3261,18 +3261,6 @@ compiler_continue(struct compiler *c, location loc) } -static location -location_of_last_executing_statement(asdl_stmt_seq *stmts) -{ - for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) { - location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i)); - if (loc.lineno > 0) { - return loc; - } - } - return NO_LOCATION; -} - /* Code generated for "try: finally: " is as follows: SETUP_FINALLY L @@ -3341,9 +3329,9 @@ compiler_try_finally(struct compiler *c, stmt_ty s) RETURN_IF_ERROR( compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup); @@ -3392,9 +3380,9 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); - loc = location_of_last_executing_statement(s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); + loc = NO_LOCATION; ADDOP_I(c, loc, RERAISE, 0); USE_LABEL(c, cleanup);