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

Terry Reedy tjreedy at udel.edu
Wed Nov 4 20:39:40 EST 2015


On 11/4/2015 5:02 PM, sjoerdjob at sjec.nl wrote:
> TL;DR: Change exception checking logic  from
>      err.__class__ in exc.__mro__

This is backwards. err.__class__ must be a (true) subclass, not a 
superclass, of exc, where err = exception instance, exc = exception class.

There are two checks in the exception process.  First, for 'raise err', 
is that err is a instance of StopIteration, which is to say, 
err.__class__ is a subclass of StopIteration.  To avoid the fakery of 
__instancecheck__ and __subclasscheck__, I presume this is implemented 
as something like one of
   StopIteration in err.__class__.__mro__
   StopIteration in type(err).__mro__
(There was a recent pydev discussion about when and why these may diverge.)

The second, for 'except exc', is that exc is a superclass (other than 
object) of type(err).  I presume this is implemented as something like
   exc in type(err)[:-1]  # exclude object class
This assume that err has already passed the first check above.

The `try` doc says "An object is compatible with an exception if it is 
the class or a base class of the exception object".  This text fails to 
exclude the object class as a compatible object.  CPython code rejects 
'except object:' with "TypeError: catching classes that do not inherit 
from BaseException is not allowed"

> to
>      isinstance(err, exc)
> Because it is more powerful,

?? This predicate is True more often than the current one because it a) 
does not exclude exc = object

 >>> isinstance(Exception(), object)
True

and b) accesses exc.__instancecheck__ (which is part of your point). 
This makes it a weaker predicate.

I don't have strong opinions at the moment about the proposal itself, 
but semantic changes in core python syntax need a PEP (once you think 
there is *some* support).

-- 
Terry Jan Reedy



More information about the Python-ideas mailing list