diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-04-24 20:58:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-24 20:58:51 (GMT) |
commit | 1c01f8d79760ca74f6d35b839d23ac408b3bb44e (patch) | |
tree | 063a9d5c424f015f313de485ece95b4a441d9b01 | |
parent | 518050ced18422fd00fadc1a81b0d942b98e2e5b (diff) | |
download | cpython-1c01f8d79760ca74f6d35b839d23ac408b3bb44e.zip cpython-1c01f8d79760ca74f6d35b839d23ac408b3bb44e.tar.gz cpython-1c01f8d79760ca74f6d35b839d23ac408b3bb44e.tar.bz2 |
gh-101517: fix line number propagation in code generated for except* (#103550)
-rw-r--r-- | Lib/bdb.py | 2 | ||||
-rw-r--r-- | Lib/test/test_bdb.py | 3 | ||||
-rw-r--r-- | Lib/test/test_pdb.py | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2023-04-14-22-35-23.gh-issue-101517.5EqM-S.rst | 1 | ||||
-rw-r--r-- | Python/compile.c | 32 |
5 files changed, 27 insertions, 15 deletions
@@ -574,6 +574,8 @@ class Bdb: line = linecache.getline(filename, lineno, frame.f_globals) if line: s += lprefix + line.strip() + else: + s += f'{lprefix}Warning: lineno is None' return s # The following methods can be called by clients to use diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index fc4b809..568c88e 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -1207,7 +1207,8 @@ class IssuesTestCase(BaseTestCase): class TestRegressions(unittest.TestCase): def test_format_stack_entry_no_lineno(self): # See gh-101517 - Bdb().format_stack_entry((sys._getframe(), None)) + self.assertIn('Warning: lineno is None', + Bdb().format_stack_entry((sys._getframe(), None))) if __name__ == "__main__": diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 94b4417..b5c413a 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -1715,8 +1715,8 @@ def test_pdb_issue_gh_101517(): ... 'continue' ... ]): ... test_function() - --Return-- - > <doctest test.test_pdb.test_pdb_issue_gh_101517[0]>(None)test_function()->None + > <doctest test.test_pdb.test_pdb_issue_gh_101517[0]>(5)test_function() + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() (Pdb) continue """ diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-14-22-35-23.gh-issue-101517.5EqM-S.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-14-22-35-23.gh-issue-101517.5EqM-S.rst new file mode 100644 index 0000000..730c6cd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-14-22-35-23.gh-issue-101517.5EqM-S.rst @@ -0,0 +1 @@ +Fix bug in line numbers of instructions emitted for :keyword:`except* <except_star>`. diff --git a/Python/compile.c b/Python/compile.c index 9c5f3aa..9603269 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3045,11 +3045,9 @@ compiler_try_except(struct compiler *c, stmt_ty s) [orig, res, exc] <evaluate E1> [orig, res, exc, E1] CHECK_EG_MATCH [orig, res, rest/exc, match?] COPY 1 - [orig, res, rest/exc, match?, match?] POP_JUMP_IF_NOT_NONE H1 - [orig, res, exc, None] POP_TOP - [orig, res, exc] JUMP L2 + [orig, res, rest/exc, match?, match?] POP_JUMP_IF_NONE C1 - [orig, res, rest, match] H1: <assign to V1> (or POP if no V1) + [orig, res, rest, match] <assign to V1> (or POP if no V1) [orig, res, rest] SETUP_FINALLY R1 [orig, res, rest] <code for S1> @@ -3057,8 +3055,14 @@ compiler_try_except(struct compiler *c, stmt_ty s) [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res [orig, res, rest, i] POP + [orig, res, rest] JUMP LE2 - [orig, res, rest] L2: <evaluate E2> + [orig, res, rest] L2: NOP ) for lineno + [orig, res, rest] JUMP LE2 + + [orig, res, rest/exc, None] C1: POP + + [orig, res, rest] LE2: <evaluate E2> .............................etc....................... [orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None) @@ -3114,7 +3118,8 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) location loc = LOC(handler); NEW_JUMP_TARGET_LABEL(c, next_except); except = next_except; - NEW_JUMP_TARGET_LABEL(c, handle_match); + NEW_JUMP_TARGET_LABEL(c, except_with_error); + NEW_JUMP_TARGET_LABEL(c, no_match); if (i == 0) { /* create empty list for exceptions raised/reraise in the except* blocks */ /* @@ -3132,13 +3137,9 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) VISIT(c, expr, handler->v.ExceptHandler.type); ADDOP(c, loc, CHECK_EG_MATCH); ADDOP_I(c, loc, COPY, 1); - ADDOP_JUMP(c, loc, POP_JUMP_IF_NOT_NONE, handle_match); - ADDOP(c, loc, POP_TOP); // match - ADDOP_JUMP(c, loc, JUMP, except); + ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match); } - USE_LABEL(c, handle_match); - NEW_JUMP_TARGET_LABEL(c, cleanup_end); NEW_JUMP_TARGET_LABEL(c, cleanup_body); @@ -3197,9 +3198,16 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) /* add exception raised to the res list */ ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc ADDOP(c, NO_LOCATION, POP_TOP); // lasti - ADDOP_JUMP(c, NO_LOCATION, JUMP, except); + ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error); USE_LABEL(c, except); + ADDOP(c, NO_LOCATION, NOP); // to hold a propagated location info + ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error); + + USE_LABEL(c, no_match); + ADDOP(c, loc, POP_TOP); // match (None) + + USE_LABEL(c, except_with_error); if (i == n - 1) { /* Add exc to the list (if not None it's the unhandled part of the EG) */ |