You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot perform frame jump after handled exception #92228
For the presented example I performed jump using PyCharm.
Not sure if I know how to reproduce it using settrace (I can try) but under the hood PyCharm is simply setting f_lineno to perform a jump.
Edit: For my library purposes I am setting f_lineno manually and it is causing the same issue
import sys
def fun():
a = 1 # <---- jump location
try:
b = 1 / 0
except ZeroDivisionError as e:
pass
c = 3 # current location
def trace(frame, event, arg):
if event == "line" and frame.f_lineno == 11:
frame.f_lineno = 4
return trace
sys.settrace(trace)
if __name__ == "__main__":
fun()
Traceback:
Traceback (most recent call last):
File "<cwd>/cakeshop.py", line 24, in <module>
fun()
^^^^^
File "<cwd>/cakeshop.py", line 11, in fun
c = 3 # current location
^
File "<cwd>/cakeshop.py", line 11, in fun
c = 3 # current location
^
File "<cwd>/cakeshop.py", line 16, in trace
frame.f_lineno = 4
^^^^^^^^^^^^^^
ValueError: can't jump from within an exception handler
You mean, the compiler can tell that it's unreachable.
If you allow the debugger to jump around you can do all kinds of impossible things (like get to the pass in your example without an exception being raised). I'm not sure what the semantics of these debugger jumps are, really.
Activity
serhiy-storchaka commentedon May 4, 2022
@markshannon
markshannon commentedon May 4, 2022
@dkrystki Do you have a full reproducer?
You haven't said how you are performing the jump.
dkrystki commentedon May 4, 2022
For the presented example I performed jump using PyCharm.
Not sure if I know how to reproduce it using settrace (I can try) but under the hood PyCharm is simply setting f_lineno to perform a jump.
Edit: For my library purposes I am setting f_lineno manually and it is causing the same issue
dkrystki commentedon May 4, 2022
I managed to make a full reproducer:
Traceback:
serhiy-storchaka commentedon May 4, 2022
serhiy-storchaka commentedon May 4, 2022
All works if add anything above or below the assignment.
sweeneyde commentedon May 14, 2022
For what it's worth, this is the problematic result from the reproducer.
Bytecode:
Details
Result from
mark_stacks():Here,
-2meansUNINITIALIZED. This is a result of the following code inmark_stacks:After
RETURN_VALUE, the rest of the stacks areUNINITIALIZEDand remainUNINITIALIZEDas they're skipped over. I don't know the correct solution.BTW, bisected to adcd220
markshannon commentedon Jun 16, 2022
I'm making this a deferred blocker.
I don't think it needs to block the next beta, but I definitely want to fix it before release
markshannon commentedon Jun 16, 2022
We need to use the exception handling table to fill in the stacks for exception handlers.
Fiddly, but not too difficult.
29 remaining items
iritkatriel commentedon Jul 11, 2022
The issue of exception handlers is tracked here: #94739
markshannon commentedon Jul 11, 2022
The jump from the example I give is from the
pass, which is outside of the except handler.iritkatriel commentedon Jul 11, 2022
I see, will check.
iritkatriel commentedon Jul 11, 2022
This fails too:
markshannon commentedon Jul 11, 2022
That should fail.
output.append(3)is unreachableiritkatriel commentedon Jul 11, 2022
You mean, the compiler can tell that it's unreachable.
If you allow the debugger to jump around you can do all kinds of impossible things (like get to the pass in your example without an exception being raised). I'm not sure what the semantics of these debugger jumps are, really.
markshannon commentedon Jul 11, 2022
No one is.
In my mind, they are:
iritkatriel commentedon Jul 11, 2022
We understand the issue, and it's the subject of #94739 so I'll close this again (the original problem reported here was resolved).