Question

The Python documentation for except says:

For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is “compatible” with the exception. An object is compatible with an exception if it is the class or a base class of the exception object, [...]

Why doesn't except use isinstance instead of comparing base classes? This is preventing the use of __instancecheck__ to override the instance check.

EDIT:

I can understand that one of the reasons this doesn't exist is that no one considered it. But are there any reasons why this should not be implemented?

EDIT:

Shell session from Python 3.2a showing that trying to use __subclasscheck__ for this doesn't work:

>>> class MyType(type): __subclasscheck__ = lambda cls, other_cls: True
>>> class O(Exception, metaclass=MyType): pass
>>> issubclass(3, O)
0: True
>>> issubclass(int, O)
1: True
>>> try:
...     1/0
... except O:
...     print('Success')
Traceback (most recent call last):
  File "<pyshell#4>", line 2, in <module>
    1/0
ZeroDivisionError: division by zero
>>> 
Was it helpful?

Solution

The simple answer is probably that nobody considered it. A more complex answer would be that nobody considered it because it's hard to get this right, because it would mean executing potentially arbitrary Python code while handling an exception, and that it is of dubious value. Exception classes in Python are typically very simple classes, and overloading them with functionality is often a mistake. It's hard to imagine a case for having it consult __instancecheck__. If you have such a case (with or without a patch), file a bug and someone might pick it up.

OTHER TIPS

But are there any reasons why this should not be implemented?

Can you give an example where this would be useful?

When you do this:

class SomeMeta(type):
    def __subclasscheck__(cls, sub):
        print (cls, sub)
        return True

class Something(Exception):
    pass

class SomeType(Exception):
    __metaclass__ = SomeMeta

try:
    raise Something()
except SomeType, e:
    pass

# prints (<class '__main__.SomeType'>, <class '__main__.Something'>)

Python calls __subclasscheck__ on SomeType's metaclass to determine if Something a subclass of SomeType. The Metaclass PEP talks about this in more detail.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top