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

Addresses issue #1636.
This commit is contained in:
Damien George 2015-12-24 12:47:39 +00:00
parent 117158fcd5
commit 8047340d75
2 changed files with 112 additions and 0 deletions

View File

@ -1032,6 +1032,14 @@ unwind_jump:;
ENTRY(MP_BC_RETURN_VALUE):
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:
while (exc_sp >= exc_stack) {
if (MP_TAGPTR_TAG1(exc_sp->val_sp)) {

View File

@ -0,0 +1,104 @@
# 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())