Author: Carl Friedrich Bolz <cfb...@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} _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit