Exception handling in Python 3.x

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Dec 3 19:42:42 EST 2010


On Fri, 03 Dec 2010 16:26:19 +0100, Hrvoje Niksic wrote:

> Peter Otten <__peter__ at web.de> writes:
> 
>>> Note that StopIteration is an internal detail of no relevance
>>> whatsoever to the caller. Expose this is unnecessary at best and
>>> confusing at worst.
>>
>> http://mail.python.org/pipermail/python-list/2010-October/1258606.html
>> http://mail.python.org/pipermail/python-list/2010-October/1259024.html

Thanks for the links Peter.

 
> Both of these involve suppressing the chaining at the wrong place,
> namely in the outer handler or, worse yet, in the exception display
> mechanism.  Steven, on the other hand, wants his *inner* handler to
> express that the original exception was an implementation detail, a
> business exception such as StopIteration, that is completely irrelevant
> to the actual exception being raised.

Yes, exactly! Python 3.x exposes completely irrelevant and internal 
details in the traceback.


> The outer handler is the wrong
> place to suppress the chaining because it has no way of distinguishing
> Steven's case from a genuine case of a new exception unexpectedly
> occurring during handling of the original exception.
> 
> One solution would be for "raise" inside except to not use the context.

I would have thought that was such an obvious solution that I was 
gobsmacked to discover the PEP 3134 hadn't already considered it. If you 
*explicitly* raise an exception inside an exception handler, surely it's 
because you want to suppress the previous exception as an internal detail?

If not, and you want to chain it with the previous exception, the 
solution is simple, obvious and straight-forward: explicit chaining.

try:
   something()
except SomeException as exc:
   raise MyException from exc




> For example:
> 
> try:
>   {}[1]
> except KeyError:
>   1/0
> 
> would behave as before, but:


Yes, that presumably would be a bug and should chain exceptions.


> But:
> 
> try:
>   {}[1]
> except KeyError:
>   raise Exception("my error")
> 
> ...would raise the custom error forgetting the KeyError.


That's exactly the behaviour I would expect and I'm surprised that this 
feature was put into production without some simple way to support this 
idiom.



-- 
Steven



More information about the Python-list mailing list