Commit 8047340d authored by Damien George's avatar Damien George

py: Handle case of return within the finally block of try-finally.

Addresses issue #1636.
parent 117158fc
...@@ -1032,6 +1032,14 @@ unwind_jump:; ...@@ -1032,6 +1032,14 @@ unwind_jump:;
ENTRY(MP_BC_RETURN_VALUE): ENTRY(MP_BC_RETURN_VALUE):
MARK_EXC_IP_SELECTIVE(); MARK_EXC_IP_SELECTIVE();
// These next 3 lines pop a try-finally exception handler, if one
// is there on the exception stack. Without this the finally block
// is executed a second time when the return is executed, because
// the try-finally exception handler is still on the stack.
// TODO Possibly find a better way to handle this case.
if (currently_in_except_block) {
POP_EXC_BLOCK();
}
unwind_return: unwind_return:
while (exc_sp >= exc_stack) { while (exc_sp >= exc_stack) {
if (MP_TAGPTR_TAG1(exc_sp->val_sp)) { if (MP_TAGPTR_TAG1(exc_sp->val_sp)) {
......
# test 'return' within the finally block
# it should swallow the exception
# simple case
def f():
try:
raise ValueError()
finally:
print('finally')
return 0
print('got here')
print(f())
# nested, return in outer
def f():
try:
try:
raise ValueError
finally:
print('finally 1')
print('got here')
finally:
print('finally 2')
return 2
print('got here')
print(f())
# nested, return in inner
def f():
try:
try:
raise ValueError
finally:
print('finally 1')
return 1
print('got here')
finally:
print('finally 2')
print('got here')
print(f())
# nested, return in inner and outer
def f():
try:
try:
raise ValueError
finally:
print('finally 1')
return 1
print('got here')
finally:
print('finally 2')
return 2
print('got here')
print(f())
# nested with reraise
def f():
try:
try:
raise ValueError
except:
raise
print('got here')
finally:
print('finally')
return 0
print('got here')
print(f())
# triple nesting with reraise
def f():
try:
try:
try:
raise ValueError
except:
raise
except:
raise
finally:
print('finally')
return 0
print(f())
# exception when matching exception
def f():
try:
raise ValueError
except NonExistingError:
pass
finally:
print('finally')
return 0
print(f())
# raising exception class, not instance
def f():
try:
raise ValueError
finally:
print('finally')
return 0
print(f())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment