Hi all,I have a weird case where I thought line events would be issued and yet they aren't even though they're in the instructions in the bytecode (both in 3.9 and 3.10).i.e.:Given the code:def check_backtrack(x): # line 1
if not (x == 'a' # line 2
or x == 'c'): # line 3
pass # line 4it has dis.dis such as:2 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 ('a')
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_TRUE 12 (to 24)
3 8 LOAD_FAST 0 (x)
10 LOAD_CONST 2 ('c')
12 COMPARE_OP 2 (==)
2 14 POP_JUMP_IF_TRUE 10 (to 20)
4 16 LOAD_CONST 0 (None)
18 RETURN_VALUE
2 >> 20 LOAD_CONST 0 (None)
22 RETURN_VALUE
>> 24 LOAD_CONST 0 (None)
26 RETURN_VALUESo, by just following the instructions/line numbers, I'd say that when the instruction:2 14 POP_JUMP_IF_TRUE 10 (to 20)is executed, a line event would take place, yet, this isn't true, but if that offset is changed to include more instructions then such a line event is issued.i.e.: something as:def tracer(frame, event, arg):
print(frame, event)
return tracer
import sys
sys.settrace(tracer)check_backtrack('f')prints:1 call
2 line
3 line
4 line
4 returnwhen I expected it to print:1 call
2 line
3 line
2 line |<-- this is not being issued
4 line
4 returnSo, I have some questions related to this:Does anyone know why this happens?What's the rule to identify this?Why is that line number assigned to that instruction (i.e.: it seems a bit odd that this is set up like that in the first place)?Thanks,Fabiop.s.: I'm asking because in a debugger which changes bytecode I want to keep the same semantics and it appears that if I add more bytecode at that instruction offset, those semantics aren't kept (but I don't really know what are the semantics to keep here since it seems like that instruction should issue a line event even though it doesn't).
TARGET(COMPARE_OP): { assert(oparg <= Py_GE); PyObject *right = POP(); PyObject *left = TOP(); PyObject *res = PyObject_RichCompare(left, right, oparg); SET_TOP(res); Py_DECREF(left); Py_DECREF(right); if (res == NULL) goto error; PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); } |