Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r98507:11a00b95fd59 Date: 2020-01-10 12:59 +0100 http://bitbucket.org/pypy/pypy/changeset/11a00b95fd59/
Log: Issue #3149 Fix the exception-matching logic to fall back to the general issubclass() logic. This is what CPython 2.x does. diff --git a/pypy/module/__builtin__/abstractinst.py b/pypy/module/__builtin__/abstractinst.py --- a/pypy/module/__builtin__/abstractinst.py +++ b/pypy/module/__builtin__/abstractinst.py @@ -219,13 +219,15 @@ return BaseObjSpace.exception_getclass(space, w_obj) def exception_issubclass_w(space, w_cls1, w_cls2): - if isinstance(w_cls1, W_ClassObject): - if isinstance(w_cls2, W_ClassObject): - return w_cls1.is_subclass_of(w_cls2) - return False - if isinstance(w_cls2, W_ClassObject): - return False - return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) + if (space.type(w_cls1) is space.w_type and + space.type(w_cls2) is space.w_type): + return BaseObjSpace.exception_issubclass_w(space, w_cls1, w_cls2) + # + # The rest is the rare slow case. Use the general logic of issubclass() + # (issue #3149). CPython 3.x doesn't do that, but there is a many-years + # issue report: https://bugs.python.org/issue12029. In PyPy3 we try to + # fix the issue with the same code, as long as no CPython3 test fails. + return abstract_issubclass_w(space, w_cls1, w_cls2, True) # ____________________________________________________________ # App-level interface diff --git a/pypy/module/__builtin__/test/test_abstractinst.py b/pypy/module/__builtin__/test/test_abstractinst.py --- a/pypy/module/__builtin__/test/test_abstractinst.py +++ b/pypy/module/__builtin__/test/test_abstractinst.py @@ -239,3 +239,23 @@ return False assert issubclass(42, M()) is False + + def test_exception_match_calls_subclasscheck(self): + class Special(Exception): + class __metaclass__(type): + def __subclasscheck__(cls1, cls2): + return True + try: + raise ValueError + except Special: + pass + + def test_exception_raising_calls_subclasscheck(self): + class Special(Exception): + class __metaclass__(type): + def __subclasscheck__(cls1, cls2): + return True + try: + raise Special, ValueError() + except ValueError: + pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit