[Python-Dev] [Python-checkins] cpython (3.2): #11669: rephrase footnote in the Compound Statements page.

Nick Coghlan ncoghlan at gmail.com
Mon Jun 27 03:27:36 CEST 2011


On Mon, Jun 27, 2011 at 12:02 AM, Sandro Tosi <sandro.tosi at gmail.com> wrote:
> I gave my interpretation of the footnote at:
> http://bugs.python.org/issue11669#msg139092 . Does this clarify it?

No, because while there *are* ways a finally clause can kill an
exception completely, reraising another exception is not really one of
them (as we set __context__ appropriately in that case, even if it
means forcing instantiation of an as yet unrealised exception).

>From PEP 3134:

"This PEP handles exceptions that occur during 'except' blocks and
'finally' blocks in the same way.  Reading the traceback makes it
clear where the exceptions occurred, so additional mechanisms for
distinguishing the two cases would only add unnecessary complexity."

And from the interactive prompt:

>>> try:
...   raise TypeError
... except TypeError:
...   raise ValueError
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ValueError
>>> try:
...   raise TypeError
... finally:
...   raise ValueError
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
TypeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ValueError

Note that PEP 3134 exception chaining means the original exception is
not lost in either case - it is available via the __context__
attribute of the subsequent exception.

However, *other* control flow statements in a finally clause *can*
mean that an exception is lost completely, just as if it had been
caught and not reraised:

- the "return" example from my first message ('yield' will allow the
exception to propagate when the generator is resumed)
- 'break' in a loop ('continue' is not permitted inside a 'finally' clause)

The old wording was at least vaguely right ("there are ways that a
finally clause can kill an exception, but we aren't going to tell you
what they are"). The new wording is precisely wrong, as it excludes
the return and break cases (in both 2.x and 3.x) and, in 3.x, fails to
note that the old exception isn't lost completely due to exception
chaining (even if it is indeed hidden from any exception handlers in
the current call stack).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list