diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index bc022a9f5cbe71470daaf20d1cc039ffaf499745..19e47cb44f60a3b4111d32a0c9a5cfaac15309cf 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1202,6 +1202,44 @@ def test_multiline_assert_rewritten_as_method_call(self): tree.body[0] = new_node compile(tree, "<test>", "exec") + def test_push_null_load_global_positions(self): + source_template = """ + import abc, dis + import ast as art + + abc = None + dix = dis + ast = art + + def f(): + {} + """ + for body in [ + " abc.a()", + " art.a()", + " ast.a()", + " dis.a()", + " dix.a()", + " abc[...]()", + " art()()", + " (ast or ...)()", + " [dis]()", + " (dix + ...)()", + ]: + with self.subTest(body): + namespace = {} + source = textwrap.dedent(source_template.format(body)) + exec(source, namespace) + code = namespace["f"].__code__ + self.assertOpcodeSourcePositionIs( + code, + "LOAD_GLOBAL", + line=10, + end_line=10, + column=4, + end_column=7, + ) + 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/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst b/Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst new file mode 100644 index 0000000000000000000000000000000000000000..2bc0d8224c6a0005e2b193ff2b9a266f948b0ec3 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-07-20-13-46-01.gh-issue-91409.dhL8Zo.rst @@ -0,0 +1,2 @@ +Fix incorrect source location info caused by certain optimizations in the +bytecode compiler. diff --git a/Python/compile.c b/Python/compile.c index 20eca059d30f10be43e8c5378a79261541e43153..52b7d9242eb2b0a90ca9f551213be6fc44e6d283 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -9278,7 +9278,10 @@ clean_basic_block(basicblock *bb) { /* or, if the next instruction has same line number or no line number */ if (src < bb->b_iused - 1) { int next_lineno = bb->b_instr[src+1].i_loc.lineno; - if (next_lineno < 0 || next_lineno == lineno) { + if (next_lineno == lineno) { + continue; + } + if (next_lineno < 0) { bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc; continue; }