Try it and see:
def failure():
raise ValueError, "Real error"
def apologize():
raise TypeError, "Apology error"
try:
failure()
except ValueError:
apologize()
raise
The result:
Traceback (most recent call last):
File "<pyshell#14>", line 10, in <module>
apologize()
File "<pyshell#14>", line 5, in apologize
raise TypeError, "Apology error"
TypeError: Apology error
The reason: the "real" error from the original function was already caught by the `except`. `apologize` raises a new error *before the `raise` is reached*. Therefore, the `raise` in the `except` clause is never executed, and only the apology's error propagates upward. If `apologize` raises an error, Python has no way of knowing that you were going to raise a different exception after `apologize`.
Note that in Python 3, the traceback will mention *both* exceptions, with a message explaining how the second one arose:
Traceback (most recent call last):
File "./prog.py", line 9, in <module>
File "./prog.py", line 2, in failure
ValueError: Real error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./prog.py", line 11, in <module>
File "./prog.py", line 5, in apologize
TypeError: Apology error
However, the second exception (the "apology" exception) is still the only one that propagates outward and can be caught by a higher-level `except` clause. The original exception is mentioned in the traceback but is subsumed in the later one and can no longer be caught.