[pypy-commit] pypy default: (cfbolz, arigo): fix the mapdict cache for subclasses of builtin types that

cfbolz pypy.commits at gmail.com
Wed Aug 24 06:42:58 EDT 2016


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: 
Changeset: r86491:46e88ff9f92f
Date: 2016-08-24 11:42 +0100
http://bitbucket.org/pypy/pypy/changeset/46e88ff9f92f/

Log:	(cfbolz, arigo): fix the mapdict cache for subclasses of builtin
	types that provide a dict

diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -1014,6 +1014,12 @@
 
 def LOOKUP_METHOD_mapdict_fill_cache_method(space, pycode, name, nameindex,
                                             w_obj, w_type, w_method):
+    # if the layout has a dict itself, then mapdict is not used for normal
+    # attributes. Then the cache won't be able to spot changes to the dict.
+    # Thus we don't cache. see test_bug_builtin_types_callmethod
+    if not w_type.layout.typedef.hasdict:
+        return
+
     if w_method is None or isinstance(w_method, MutableCell):
         # don't cache the MutableCell XXX could be fixed
         return
diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -1217,6 +1217,23 @@
         got = x.a
         assert got == 'd'
 
+    def test_bug_builtin_types_callmethod(self):
+        import sys
+        class D(type(sys)):
+            def mymethod(self):
+                return "mymethod"
+
+        def foobar():
+            return "foobar"
+
+        d = D('d')
+        res1 = d.mymethod()
+        d.mymethod = foobar
+        res2 = d.mymethod()
+        assert res1 == "mymethod"
+        assert res2 == "foobar"
+
+
 class AppTestGlobalCaching(AppTestWithMapDict):
     spaceconfig = {"objspace.std.withmethodcachecounter": True}
 


More information about the pypy-commit mailing list