[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

"except" and "subclasscheck" changed between CPython2 and 3


I found a difference of behavior about `except` statement between CPython
2.7 and 3.x .
`except EXC_CLASS:` calls `__subclasscheck__` in 2.7, but does not in 3.x .

Let me show you an example.
Now, define a class "ExceptionLike" (with metaclass "ExceptionLikeMeta")

class ExceptionLikeMeta(type):
    def __subclasscheck__(cls, other):
        return other.__name__.endswith('Exception')

ExceptionLike = ExceptionLikeMeta('ExceptionLike', (Exception,), {})

    raise Exception()
except ExceptionLike:
    print('catch it!')
    assert False, 'not caught!'

The exception is caught with `ExceptionLike` in 2.7, but not in 3.x .
(I tested it with CPython 3.6.2 and 2.7.13 on mac)

The difference seems to be introduced with this commit [
and this ticket [https://bugs.python.org/issue2534].

The behavior of CPython 3 may have some advantages.

- `except EXC_TYPE:` does never raise an exception caused by
- (may be) fast, because it just scan mro.

So, the diff can be intended one. But the ticket itself seems not.

Should not I expect that `__subclasscheck__` is used for subclass checking
anywhere? It effects only `issubclass` anymore?
(or, should I go to other list?)

youta.t at gmail.com