From d8f27cb1141fd3575de816438ed80a916c0560ed Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 19 Jun 2024 05:56:36 -0700 Subject: [PATCH] gh-120722: Set position on RETURN_VALUE in lambda (#120724) --- 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 e3e86b89246..a7c20cbcd35 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -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 index 00000000000..df83e69c601 --- /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 53fe6db5ed2..18c507b3756 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2968,7 +2968,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); }