Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit