Closed
Description
Take this example function from #107901:
def f():
for i in range(30000000):
if not i%1000000:
pass
dis.dis
produces the following output:
1 0 RESUME 0
2 2 LOAD_GLOBAL 1 (range + NULL)
12 LOAD_CONST 1 (30000000)
14 CALL 1
22 GET_ITER
>> 24 FOR_ITER 14 (to 56)
28 STORE_FAST 0 (i)
3 30 LOAD_FAST 0 (i)
32 LOAD_CONST 2 (1000000)
34 BINARY_OP 6 (%)
38 TO_BOOL
46 POP_JUMP_IF_FALSE 2 (to 52)
48 JUMP_BACKWARD 14 (to 24)
4 >> 52 JUMP_BACKWARD 16 (to 24)
2 >> 56 END_FOR
58 RETURN_CONST 0 (None)
Which has incorrect line numbers.
The issue is not that the line numbers are wrong, but that you can't tell from the dis
output.
The whole point of dis
is show what is going on at the bytecode level, so it is failing if it gives wrong line numbers.
The actual line numbers can be see from co_lines()
>>> list(f.__code__.co_lines())
[(0, 2, 1), (2, 30, 2), (30, 48, 3), (48, 52, None), (52, 56, 4), (56, 60, 2)]
The correct output should be:
1 0 RESUME 0
2 2 LOAD_GLOBAL 1 (range + NULL)
12 LOAD_CONST 1 (30000000)
14 CALL 1
22 GET_ITER
>> 24 FOR_ITER 14 (to 56)
28 STORE_FAST 0 (i)
3 30 LOAD_FAST 0 (i)
32 LOAD_CONST 2 (1000000)
34 BINARY_OP 6 (%)
38 TO_BOOL
46 POP_JUMP_IF_FALSE 2 (to 52)
None 48 JUMP_BACKWARD 14 (to 24)
4 >> 52 JUMP_BACKWARD 16 (to 24)
2 >> 56 END_FOR
58 RETURN_CONST 0 (None)