osdir.com

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

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


Hello,

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")
below.


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

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

try:
    raise Exception()
except ExceptionLike:
    print('catch it!')
except:
    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 [
https://github.com/python/cpython/commit/ec569b794737be248671d0dfac11b664fc930eef#diff-73da65b698644ee286bc60b703916bbbL163]
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
`__subclasscheck__`.
- (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