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)
Linked PRs
Take this example function from #107901:
dis.disproduces the following output:Which has incorrect line numbers.
The issue is not that the line numbers are wrong, but that you can't tell from the
disoutput.The whole point of
disis 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()The correct output should be:
Linked PRs