Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: py3.5
Changeset: r92526:ba1da1c2d9a3
Date: 2017-10-01 13:31 +0200
http://bitbucket.org/pypy/pypy/changeset/ba1da1c2d9a3/

Log:    (arigo, ronan) 'Fix' subclass checking when the subclass doesn't
        have an MRO yet, cf. CPython issue #22735

diff --git a/pypy/module/__builtin__/test/test_descriptor.py 
b/pypy/module/__builtin__/test/test_descriptor.py
--- a/pypy/module/__builtin__/test/test_descriptor.py
+++ b/pypy/module/__builtin__/test/test_descriptor.py
@@ -258,6 +258,17 @@
         raises(TypeError, "super(D).__get__(12)")
         raises(TypeError, "super(D).__get__(C())")
 
+    def test_super_incomplete(self):
+        """
+        class M(type):
+            def mro(cls):
+                if cls.__mro__ is None:
+                    raises(AttributeError, lambda: super(cls, cls).xxx)
+                return type.mro(cls)
+        class A(metaclass=M):
+            pass
+        """
+
     def test_classmethods_various(self):
         class C(object):
             def foo(*a): return a
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -156,6 +156,7 @@
                           '_version_tag?',
                           'name?',
                           'mro_w?[*]',
+                          'hasmro?',
                           ]
 
     # wether the class has an overridden __getattribute__
@@ -1346,7 +1347,21 @@
 # ____________________________________________________________
 
 def _issubtype(w_sub, w_type):
-    return w_type in w_sub.mro_w
+    if w_sub.hasmro:
+        return w_type in w_sub.mro_w
+    else:
+        return _issubtype_slow_and_wrong(w_sub, w_type)
+
+def _issubtype_slow_and_wrong(w_sub, w_type):
+    # This is only called in strange cases where w_sub is partially 
initialised,
+    # like from a custom MetaCls.mro(). Note that it's broken wrt. multiple
+    # inheritance, but that's what CPython does.
+    w_cls = w_sub
+    while w_cls:
+        if w_cls is w_type:
+            return True
+        w_cls = find_best_base(w_cls.bases_w)
+    return False
 
 @elidable_promote()
 def _pure_issubtype(w_sub, w_type, version_tag1, version_tag2):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to