try finally with a return and an exception
s-cork opened this issue · comments
def foo():
try:
return
finally:
print("finally")
1/0
foo()
In the above example I'd expect finally to get printed only once.
But in skulpt finally is printed twice.
A similar thing happens in a context manager's __exit__
method.
(if there is a return in the with statement and the __exit__
block raises, it will get called again).
The bug is caused in compile code in the Return
case.
We jump to the finally block before we've cleaned up the exception blocks.
Which means we don't pop the $exc
object correctly.
So when the finally block raises, we still have an exception block in the $exc
array.
And the final handler says oh wait, we still have an exception block to visit, let's go visit it.
It's worse if we have Exception handlers
def foo():
try:
return
except:
print("except")
return
finally:
print("finally")
1/0
foo()
# finally, except, finally, finally