[pypy-commit] pypy merge-2.7.2: Respect __subclasscheck__ when rebinding a method to a more specific class.

amauryfa noreply at buildbot.pypy.org
Sun Jan 22 14:35:38 CET 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: merge-2.7.2
Changeset: r51645:24cea2c24401
Date: 2012-01-22 14:33 +0100
http://bitbucket.org/pypy/pypy/changeset/24cea2c24401/

Log:	Respect __subclasscheck__ when rebinding a method to a more specific
	class. This change is needed to make OrderedDict() work at all, but
	it may have unexpected performance impact.

diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -497,7 +497,8 @@
             # only allow binding to a more specific class than before
             if (w_cls is not None and
                 not space.is_w(w_cls, space.w_None) and
-                not space.abstract_issubclass_w(w_cls, self.w_class)):
+                not space.is_true(
+                    space.issubtype_allow_override(w_cls, self.w_class))):
                 return space.wrap(self)    # subclass test failed
             else:
                 return descr_function_get(space, self.w_function, w_obj, w_cls)
diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -641,6 +641,19 @@
         assert issubclass(B, B)
         assert issubclass(23, B)
 
+    def test_issubclass_and_method(self):
+        class Meta(type):
+            def __subclasscheck__(cls, sub):
+                if sub is Dict:
+                    return True
+        class A:
+            __metaclass__ = Meta
+            def method(self):
+                return 42
+        class Dict:
+            method = A.method
+        assert Dict().method() == 42
+
     def test_truth_of_long(self):
         class X(object):
             def __len__(self): return 1L


More information about the pypy-commit mailing list