return eats exception

Question:

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?

Asked By: nosklo

||

Answers:

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

Answered By: Max Schmeling

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

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.

Answered By: SilentGhost

Here is an interesting comparison for return in finally block, among – Java/C#/Python/JavaScript: (archive link)

Return From Finally

Just today I was helping with some bug in Java and came across
interesting problem – what happens if you use return within try/catch
statement? Should the finally section fire up or not? I simplified the
problem to following code snippet:

What does the following code print out?

class ReturnFromFinally {  
 public static int a() {  
  try {  
   return 1;  
  }  
  catch (Exception e) {}  
  finally{  
   return 2;  
  }  
 }  

        public static void main(String[] args) {  
  System.out.println(a());  
        }  
}  

My initial guess would be, that it should print out 1, I’m calling
return, so I assume, one will be returned. However, it is not the
case:

the second return is executed

I understand the logic, finally section has to be executed, but
somehow I feel uneasy about this. Let’s see what C# does in this case:

class ReturnFromFinally  
{  
 public static int a()  
 {  
  try {  
          return 1;  
  }  
  catch (System.Exception e) {}  
  finally   
  {   
   return 2;  
  }  
 }  

 public static void Main(string[] args)  
 {  
  System.Console.WriteLine(a());  
 }  
}  

error CS0157 Control cannot leave the body of a finally clause

I prefer much rather this behavior, control flow cannot be messed with
in finally clause, so it prevents us from shooting ourself in the
foot. Just for the sake of completeness, let’s check what other
languages do.

Python:

def a():  
 try:  
  return 1  
 finally:  
  return 2  
print a()  

Python returns 2 as well

JavaScript:

<script>  
function ReturnFromFinally()  
{  
 try  
 {  
  return 1;  
 }  
 catch (e)  
 {  
 }  
 finally  
 {  
  return 2;  
 }  
}  
</script>  
<a onclick="alert(ReturnFromFinally());">Click here</a>  

JavaScript returns 2 as well

There is no finally clause in C++ and PHP, so I can’t try out the last
two languages I have compiler/interpreter for.

Our little experiment nicely showed, that C# has the nicest approach
to this problem, but I was quite surprised to learn, that all the
other languages handle the problem the same way.

Answered By: JV.

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).

Answered By: Carl Meyer
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.