diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 80b32dee0665f7a7a7890feef6737247aa502919..e22696499e236c2f100a0808c6df39099d73b2ab 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1166,6 +1166,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 3fe0930e7aebf0fbf216d8e1e661770ca9a3d266..e8acd8597778daea45cb33ebb50278fecc2e6743 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -9045,7 +9045,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_lineno; - if (next_lineno < 0 || next_lineno == lineno) { + if (next_lineno == lineno) { + continue; + } + if (next_lineno < 0) { COPY_INSTR_LOC(bb->b_instr[src], bb->b_instr[src+1]); continue; }