views:

125

answers:

2

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
>>> 
+1  A: 

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.

Thomas Wouters
I can relate with the fact that nobody considered it. I guess what I'm asking is if there are good reasons not to do it. *"it would mean executing potentially arbitrary Python code while handling an exception"*. I think I can give the "consenting adults" answer to that-- If someone wants to have a custom instance check in his exception handling, why not let him?
cool-RR
+1  A: 

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.

THC4k
I tried your `__subclasscheck__` suggestion now on both 2.6 and 3.2a, unfortunately it didn't work. About your question: What do you mean in "concrete"? An example for this being useful?
cool-RR
@cool-RR yeah, i clarified it a bit.
THC4k
Okay, I see that both our samples do work in 2.6, but not in 3.1 or 3.2a.
cool-RR
About an example where this would be useful: I have an idea of making something like `abc` for exceptions, so you can register an exception instance to be also an instance of a different exception type. This could prevent annoying traceback-hiding when catching an exception only to raise another.
cool-RR