[Python-ideas] Use `isinstance` check during exception handling

sjoerdjob at sjec.nl sjoerdjob at sjec.nl
Thu Nov 5 10:00:34 EST 2015


> On Nov 4, 2015, at 14:02, sjoerdjob at sjec.nl wrote:
>>
>> Hi all,
>>
>> TL;DR: Change exception checking logic from
>>    err.__class__ in exc.__mro__
>> to
>>    isinstance(err, exc)
>> Because it is more powerful, more consistent and allows for cleaner
>> code.
>
> Correct me if I'm wrong, but doesn't Python allow you to raise a class and
> handle it without ever creating an instance? If an instance is needed
> (e.g., because the exception is caught by a handler with an as clause),
> one is created by calling exc(), but if it's not needed, that doesn't
> happen.
>
> Assuming I'm right, your proposal would mean the instance is _always_
> needed, so if you raise a type, exc() is always called. So, for example:
>
>     class MyException(Exception):
>         def __init__(self, thingy, *a, **kw):
>             super().__init__(*a, **kw)
>             self.thingy = thingy
>
>     try:
>         raise MyException
>     except MyException:
>         print('whoops')
>
> Instead of printing "whoops", it would now (I think) abort with a
> TypeError about trying to call MyException with the wrong number of
> arguments.

Yes, the exception is instantiated as soon as it is raised (not when it's
matched). This happens in Python/ceval.c. So you actually have to catch
`TypeError` in this case.

> Plus, there's almost certainly code where someone skips creating the
> instance as an optimization—probably it's usually a useless premature
> one, but maybe someone has tested and it makes a difference in a real
> program.

It will get instantiated anyway.

> One obvious possibility is: if exc is itself a subclass of BaseException,
> you use the existing subclass check; if not, instead of using the subclass
> check on its type, you use the new instance check. But you'd have to think
> that through to make sure it makes sense.



More information about the Python-ideas mailing list