views:

474

answers:

4

I found the following behavior at least weird:

def errors():
    try:
        ErrorErrorError
    finally:
        return 10

print errors()
# prints: 10
# It should raise: NameError: name 'ErrorErrorError' is not defined

The exception disappears when you use return inside a finally clause. Is that a bug? Is that documented anywhere?

But the real question (and the answer I will mark as correct) is:
What is the python developers' reason to allow that odd behavior?

+2  A: 

Returning from a finally is not a good idea. I know C# specifically forbids doing this.

Max Schmeling
+26  A: 

it is

If finally is present, it specifies a ‘cleanup’ handler. The try clause is executed, including any except and else clauses. If an exception occurs in any of the clauses and is not handled, the exception is temporarily saved. The finally clause is executed. If there is a saved exception, it is re-raised at the end of the finally clause. If the finally clause raises another exception or executes a return or break statement, the saved exception is lost.

SilentGhost
+1: Quote the documentation.
S.Lott
Bam. This is what **I** was after. You nailed it :P
Matt Joiner
QFT? O.o (four)
Wayne Werner
+3  A: 

Here is an interesting comparison for return in finally block, among - Java/C#/Python/Javascipt: http://www.gettingclever.com/2008/07/return-from-finally.html

JV
No surprise there. All the languages do the only sensible thing (honor the finally clause), except C#, which prevents shooting yourself in the foot. That wouldn't be in the spirit of Python, which _always_ gives you all the rope you need to hang yourself :-) "We're all consenting adults here."
Carl Meyer
+12  A: 

You asked about the Python developers' reasoning. I can't speak for them, but no other behavior makes sense. A function can either return a value, or it can raise an exception; it can't do both. The purpose of a "finally" clause is to provide cleanup code that is "guaranteed" to be run, regardless of exceptions. By putting a return statement in a finally clause, you have declared that you want to return a value, no matter what, regardless of exceptions. If Python behaved as you are asking and raised the exception, it would be breaking the contract of the "finally" clause (because it would fail to return the value you told it to return).

Carl Meyer