diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index c756d43a3cf3b8..8a6eb1ad97bed7 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -990,6 +990,20 @@ async def test(aseq): code_lines = self.get_code_lines(test.__code__) self.assertEqual(expected_lines, code_lines) + def test_lineno_of_backward_jump(self): + # Issue gh-107901 + def f(): + for i in x: + if y: + pass + + linenos = list(inst.positions.lineno + for inst in dis.get_instructions(f.__code__) + if inst.opname == 'JUMP_BACKWARD') + + self.assertTrue(len(linenos) > 0) + self.assertTrue(all(l is not None for l in linenos)) + def test_big_dict_literal(self): # The compiler has a flushing point in "compiler_dict" that calls compiles # a portion of the dictionary literal when the loop that iterates over the items diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-08-22-18-38-45.bpo-107901.XgXVgU.rst b/Misc/NEWS.d/next/Core and Builtins/2023-08-22-18-38-45.bpo-107901.XgXVgU.rst new file mode 100644 index 00000000000000..112e093736dd5d --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-08-22-18-38-45.bpo-107901.XgXVgU.rst @@ -0,0 +1 @@ +Fix missing line number on :opcode:`JUMP_BACKWARD` at the end of a for loop. diff --git a/Python/compile.c b/Python/compile.c index 558df3fca653ea..e0cba41c1d7d3d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3123,7 +3123,7 @@ compiler_for(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ - UNSET_LOC(c); + SET_LOC(c, s->v.For.iter); ADDOP_JUMP(c, JUMP, start); compiler_use_next_block(c, cleanup);