weird try/finally behaviour

Terry Reedy tjreedy at
Sat Apr 11 02:19:36 CEST 2009

Sylvain Thénault wrote:
> Hi there,
> I've encountered the following behaviour which I found surprising:
>>>> def test():
> ...     for x in ('test', 'tests'):
> ...          try:
> ...             if True:
> ...                   print 'return'
> ...                   return 1
> ...          finally:
> ...             print 'break'
> ...             break
> ...     print 'end'
> ... 
>>>> test()
> return
> break
> end

If you say 'print test()', you shoud see None printed after 'end' (at 
least with 3.0) from the function falling off the end.

The 'if True:' line make no difference.

> As you can see, the 'break' in the finally block makes the 'return 1' beeing ignored.
> Is this a known caveat or should it be considered as a bug?

Neither, but it s a bit subtle.  If you replace 'break' with 'return 2', 
what would you expect?  What does happen is that 2, not 1, is returned. 
  Similarly, the break sends control to "print 'end'" and thence to the 
implicit 'return None'.

The try doc on finally says "If the finally clause raises another 
exception or executes a return or break statement, the saved exception 
is lost."  The same is true for saved returns, for the same reason: the 
implicit END-FINALLY (an actual byte code) that completes the pending 
return/exception is never reached.

When works again, I will try to remember to suggest a 
doc improvement.

Terry Jan Reedy

More information about the Python-list mailing list