Exception Handling in Python 3

Ethan Furman ethan at stoneleaf.us
Fri Oct 29 13:57:25 EDT 2010


MRAB wrote:
> On 24/10/2010 13:28, Steve Holden wrote:
>> On 10/24/2010 4:48 AM, Martin v. Loewis wrote:
>>> Am 24.10.2010 07:01, schrieb Steve Holden:
>>>> I was somewhat surprised to discover that Python 3 no longer allows an
>>>> exception to be raised in an except clause (or rather that it 
>>>> reports it
>>>> as a separate exception that occurred during the handling of the 
>>>> first).
>>>
>>> I think you are misinterpreting what you are seeing. The exception being
>>> raised actually *is* an attribute error, and it actually is the
>>> attribute error that gets reported. It's only that reporting an
>>> exception that has a __context__ first reports the context, then reports
>>> the actual exception.
>>>
>> I don't believe I *am* misinterpreting it. The fact of the matter is
>> that the context is irrelevant to the user, and there should be some way
>> to suppress it to avoid over-complicating the traceback.
>>
>> This behavior is quite reasonable during testing, but I would prefer to
>> exclude an explicit raise directly in the except handler since that is
>> hardly to be construed as accidental (whereas an exception in a function
>> called in the handler perhaps *should* be reported).
>>
>>> You may now wonder whether it is possible to set __context__ to None
>>> somehow. See PEP 3134:
>>>
>>> Open Issue: Suppressing Context
>>>
>>>      As written, this PEP makes it impossible to suppress '__context__',
>>>      since setting exc.__context__ to None in an 'except' or 'finally'
>>>      clause will only result in it being set again when exc is raised.
>>>
>> I have already read that. Peter Otten has separately explained how to
>> suppress the behavior using sys.excepthook, which appears to be a
>> halfway satisfactory solution.
>>
> Suggestion: an explicit 'raise' in the exception handler excludes the 
> context, but if you want to include it then 'raise with'. For example:
> 
> # Exclude the context
> try:
>     command_dict[command]()
> except KeyError:
>     raise CommandError("Unknown command")
> 
> # Include the context
> try:
>     command_dict[command]()
> except KeyError:
>     raise with CommandError("Unknown command")

+1

Presumably, this would also keep the context if an actual error occured.

~Ethan~



More information about the Python-list mailing list