To start I tried this
def x():
try:
1/0 # just an division error to get an exception
except:
x()
And this code behaves normally in 3.10 and I get RecursionError: maximum recursion depth exceeded
as I expected but 3.8 goes into a stack overflow and doesn't handle the recursion error properly. But I did remember that there was RecursionError
in older versions of Python too, so I tried
def x(): x()
And this gives back RecursionError
in both versions of Python.
It's as if (in the first snippet) the recursion error is never thrown in the except but the function called and then the error thrown at the first instruction of the function called but handled by the try-except.
I then tried something else:
def x():
try:
x()
except:
x()
This is even weirder in some way, stack overflow below 3.10 but it get stuck in the loop in 3.10
Can you explain this behavior?
UPDATE
@MisterMiyagi found a even stranger behavior, adding a statement in the except in <=python3.9
doesn't result in a stackoverflow
def x():
try:
1/0
except:
print("")
x()
The different behaviors for 3.10 and other versions seem to be because of a Python issue (python/cpython#86666), you can also see the correct error on Python 2.7.
The print "fixes" things because it makes Python check the recursion limit again, and through a path that is presumably not broken. You can see the code where it does that here, it also skips the repeated check if the object supports the Vectorcall calling protocol, so things like int
keep the fatal error.