]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-120722: Set position on RETURN_VALUE in lambda (GH-120724) (#120738)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 19 Jun 2024 13:22:21 +0000 (15:22 +0200)
committerGitHub <noreply@github.com>
Wed, 19 Jun 2024 13:22:21 +0000 (13:22 +0000)
(cherry picked from commit d8f27cb1141fd3575de816438ed80a916c0560ed)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Lib/test/test_compile.py
Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst [new file with mode: 0644]
Python/compile.c

index 6be6155f1db95a50b57834f0b00522efa86521cf..e29c95e8bf263a312919ead9159bd1a182d648c8 100644 (file)
@@ -15,7 +15,7 @@ import warnings
 import _testinternalcapi
 
 from test import support
-from test.support import (script_helper, requires_debug_ranges,
+from test.support import (script_helper, requires_debug_ranges, run_code,
                           requires_specialization, get_c_recursion_limit)
 from test.support.bytecode_helper import instructions_with_positions
 from test.support.os_helper import FakePath
@@ -2028,6 +2028,33 @@ class TestSourcePositions(unittest.TestCase):
             code, "LOAD_GLOBAL", line=3, end_line=3, column=4, end_column=9
         )
 
+    def test_lambda_return_position(self):
+        snippets = [
+            "f = lambda: x",
+            "f = lambda: 42",
+            "f = lambda: 1 + 2",
+            "f = lambda: a + b",
+        ]
+        for snippet in snippets:
+            with self.subTest(snippet=snippet):
+                lamb = run_code(snippet)["f"]
+                positions = lamb.__code__.co_positions()
+                # assert that all positions are within the lambda
+                for i, pos in enumerate(positions):
+                    with self.subTest(i=i, pos=pos):
+                        start_line, end_line, start_col, end_col = pos
+                        if i == 0 and start_col == end_col == 0:
+                            # ignore the RESUME in the beginning
+                            continue
+                        self.assertEqual(start_line, 1)
+                        self.assertEqual(end_line, 1)
+                        code_start = snippet.find(":") + 2
+                        code_end = len(snippet)
+                        self.assertGreaterEqual(start_col, code_start)
+                        self.assertLessEqual(end_col, code_end)
+                        self.assertGreaterEqual(end_col, start_col)
+                        self.assertLessEqual(end_col, code_end)
+
 
 class TestExpectedAttributes(unittest.TestCase):
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst b/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst
new file mode 100644 (file)
index 0000000..df83e69
--- /dev/null
@@ -0,0 +1,2 @@
+Correctly set the bytecode position on return instructions within lambdas.
+Patch by Jelle Zijlstra.
index a24764c92fe5fbaadd9d750198e88ec77b677b9a..78ed44e78d4a9db12602286f3d393cfd4cca370b 100644 (file)
@@ -3043,7 +3043,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
         co = optimize_and_assemble(c, 0);
     }
     else {
-        location loc = LOCATION(e->lineno, e->lineno, 0, 0);
+        location loc = LOC(e->v.Lambda.body);
         ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
         co = optimize_and_assemble(c, 1);
     }