Skip to content

Commit a24e676

Browse files
authored
[3.10] gh-92311: Let frame_setlineno jump over listcomps (GH-92717)
1 parent 5d62759 commit a24e676

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

Diff for: Lib/test/test_sys_settrace.py

+48
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,54 @@ def gen():
20942094
yield 3
20952095
next(gen())
20962096
output.append(5)
2097+
2098+
@jump_test(2, 3, [1, 3])
2099+
def test_jump_forward_over_listcomp(output):
2100+
output.append(1)
2101+
x = [i for i in range(10)]
2102+
output.append(3)
2103+
2104+
# checking for segfaults.
2105+
# See https://github.com/python/cpython/issues/92311
2106+
@jump_test(3, 1, [])
2107+
def test_jump_backward_over_listcomp(output):
2108+
a = 1
2109+
x = [i for i in range(10)]
2110+
c = 3
2111+
2112+
@jump_test(8, 2, [2, 7, 2])
2113+
def test_jump_backward_over_listcomp_v2(output):
2114+
flag = False
2115+
output.append(2)
2116+
if flag:
2117+
return
2118+
x = [i for i in range(5)]
2119+
flag = 6
2120+
output.append(7)
2121+
output.append(8)
2122+
2123+
@async_jump_test(2, 3, [1, 3])
2124+
async def test_jump_forward_over_async_listcomp(output):
2125+
output.append(1)
2126+
x = [i async for i in asynciter(range(10))]
2127+
output.append(3)
2128+
2129+
@async_jump_test(3, 1, [])
2130+
async def test_jump_backward_over_async_listcomp(output):
2131+
a = 1
2132+
x = [i async for i in asynciter(range(10))]
2133+
c = 3
2134+
2135+
@async_jump_test(8, 2, [2, 7, 2])
2136+
async def test_jump_backward_over_async_listcomp_v2(output):
2137+
flag = False
2138+
output.append(2)
2139+
if flag:
2140+
return
2141+
x = [i async for i in asynciter(range(5))]
2142+
flag = 6
2143+
output.append(7)
2144+
output.append(8)
20972145

20982146

20992147
if __name__ == "__main__":
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a bug where setting ``frame.f_lineno`` to jump over a list comprehension could misbehave or crash.

Diff for: Objects/frameobject.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,10 @@ markblocks(PyCodeObject *code_obj, int len)
195195
break;
196196
case GET_ITER:
197197
case GET_AITER:
198-
block_stack = push_block(block_stack, Loop);
198+
// For-loops get a Loop block, but comprehensions do not.
199+
if (_Py_OPCODE(code[i + 1]) != CALL_FUNCTION) {
200+
block_stack = push_block(block_stack, Loop);
201+
}
199202
blocks[i+1] = block_stack;
200203
break;
201204
case FOR_ITER:

0 commit comments

Comments
 (0)