From d62cbba235df1199b8b2556d2016d37522608973 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 19 Jun 2024 06:19:39 -0700 Subject: [PATCH] [3.12] gh-120722: Set position on RETURN_VALUE in lambda (GH-120724) (#120739) (cherry picked from commit d8f27cb1141fd3575de816438ed80a916c0560ed) --- Lib/test/test_compile.py | 29 ++++++++++++++++++- ...-06-18-22-41-05.gh-issue-120722.rS7tkE.rst | 2 ++ Python/compile.c | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 6ed7fe2b0659..4fd71c0c1630 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -10,7 +10,7 @@ import types import textwrap import warnings 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, C_RECURSION_LIMIT) from test.support.os_helper import FakePath @@ -1829,6 +1829,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 TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object 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 index 000000000000..df83e69c601a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-06-18-22-41-05.gh-issue-120722.rS7tkE.rst @@ -0,0 +1,2 @@ +Correctly set the bytecode position on return instructions within lambdas. +Patch by Jelle Zijlstra. diff --git a/Python/compile.c b/Python/compile.c index 5e96a9665618..bd1650e23378 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2966,7 +2966,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); } -- 2.47.3