]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-101517: fix line number propagation in code generated for except* (#103550)
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>
Mon, 24 Apr 2023 20:58:51 +0000 (14:58 -0600)
committerGitHub <noreply@github.com>
Mon, 24 Apr 2023 20:58:51 +0000 (21:58 +0100)
Lib/bdb.py
Lib/test/test_bdb.py
Lib/test/test_pdb.py
Misc/NEWS.d/next/Core and Builtins/2023-04-14-22-35-23.gh-issue-101517.5EqM-S.rst [new file with mode: 0644]
Python/compile.c

index 7f9b09514ffd00ea9cda0d56a014a79ea16ada21..0f3eec653baaad49553f0dffe238b3e0aa5f0550 100644 (file)
@@ -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
index fc4b809431633214c4a05cb988cb2b32dd589fc2..568c88e326c0873b59447532fd25bb97a2a1bf69 100644 (file)
@@ -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__":
index 94b441720f258cc416baa9e7d176e6c221134167..b5c413af344c93decb5a04a929312bdf5901bdaf 100644 (file)
@@ -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 (file)
index 0000000..730c6cd
--- /dev/null
@@ -0,0 +1 @@
+Fix bug in line numbers of instructions emitted for :keyword:`except* <except_star>`.
index 9c5f3aabf375104b5fb784cb62a38dac1825d6f0..9603269d2b2a9d2c94c2872b1356276c12d9a3b9 100644 (file)
@@ -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) */