[pypy-commit] pypy default: (antocuni, cfbolz around): reverse-engineer what's going on, and document it
antocuni
noreply at buildbot.pypy.org
Wed Apr 18 16:01:59 CEST 2012
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r54499:c20aa5de87cf
Date: 2012-04-18 16:00 +0200
http://bitbucket.org/pypy/pypy/changeset/c20aa5de87cf/
Log: (antocuni, cfbolz around): reverse-engineer what's going on, and
document it
diff --git a/pypy/objspace/std/test/test_methodcache.py b/pypy/objspace/std/test/test_methodcache.py
--- a/pypy/objspace/std/test/test_methodcache.py
+++ b/pypy/objspace/std/test/test_methodcache.py
@@ -63,8 +63,31 @@
assert a.f() == 42 + i
A.f = eval("lambda self: %s" % (42 + i + 1, ))
cache_counter = __pypy__.method_cache_counter("f")
- # the cache hits come from A.f = ..., which first does a lookup on A as
- # well
+ #
+ # a bit of explanation about what's going on. (1) is the line "a.f()"
+ # and (2) is "A.f = ...".
+ #
+ # at line (1) we do the lookup on type(a).f
+ #
+ # at line (2) we do a setattr on A. However, descr_setattr does also a
+ # lookup of type(A).f i.e. type.f, to check if by chance 'f' is a data
+ # descriptor.
+ #
+ # At the first iteration:
+ # (1) is a miss because it's the first lookup of A.f. The result is cached
+ #
+ # (2) is a miss because it is the first lookup of type.f. The
+ # (non-existant) result is cached. The version of A changes, and 'f'
+ # is changed to be a cell object, so that subsequest assignments won't
+ # change the version of A
+ #
+ # At the second iteration:
+ # (1) is a miss because the version of A changed just before
+ # (2) is a hit, because type.f is cached. The version of A no longer changes
+ #
+ # At the third and subsequent iterations:
+ # (1) is a hit, because the version of A did not change
+ # (2) is a hit, see above
assert cache_counter == (17, 3)
def test_subclasses(self):
More information about the pypy-commit
mailing list