weird try/finally behaviour

Terry Reedy tjreedy at udel.edu
Fri Apr 10 20:19:36 EDT 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 bugs.python.org works again, I will try to remember to suggest a 
doc improvement.

Terry Jan Reedy




More information about the Python-list mailing list