Mercurial > cpython-lru_cache-weakref
annotate Lib/test/test_code.py @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | e1dbc72bd97f |
| children |
| rev | line source |
|---|---|
| 35742 | 1 """This module includes tests of the code object representation. |
| 2 | |
| 3 >>> def f(x): | |
| 4 ... def g(y): | |
| 5 ... return x + y | |
| 6 ... return g | |
| 7 ... | |
| 8 | |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
9 >>> dump(f.__code__) |
| 35742 | 10 name: f |
| 11 argcount: 1 | |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
12 kwonlyargcount: 0 |
| 35742 | 13 names: () |
| 14 varnames: ('x', 'g') | |
| 15 cellvars: ('x',) | |
| 16 freevars: () | |
| 17 nlocals: 2 | |
| 18 flags: 3 | |
|
73738
e1dbc72bd97f
PEP 3155 / issue #13448: Qualified name for classes and functions.
Antoine Pitrou <solipsis@pitrou.net>
parents:
66310
diff
changeset
|
19 consts: ('None', '<code object g>', "'f.<locals>.g'") |
| 35742 | 20 |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
21 >>> dump(f(4).__code__) |
| 35742 | 22 name: g |
| 23 argcount: 1 | |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
24 kwonlyargcount: 0 |
| 35742 | 25 names: () |
| 26 varnames: ('y',) | |
| 27 cellvars: () | |
| 28 freevars: ('x',) | |
| 29 nlocals: 1 | |
| 30 flags: 19 | |
| 31 consts: ('None',) | |
| 32 | |
| 33 >>> def h(x, y): | |
| 34 ... a = x + y | |
| 35 ... b = x - y | |
| 36 ... c = a * b | |
| 37 ... return c | |
|
36121
686306a67e9b
Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents:
35742
diff
changeset
|
38 ... |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
39 |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
40 >>> dump(h.__code__) |
| 35742 | 41 name: h |
| 42 argcount: 2 | |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
43 kwonlyargcount: 0 |
| 35742 | 44 names: () |
| 45 varnames: ('x', 'y', 'a', 'b', 'c') | |
| 46 cellvars: () | |
| 47 freevars: () | |
| 48 nlocals: 5 | |
| 49 flags: 67 | |
| 50 consts: ('None',) | |
| 51 | |
| 52 >>> def attrs(obj): | |
|
40785
22760d53d4da
Fix a bunch of doctests with the -d option of refactor.py.
Guido van Rossum <guido@python.org>
parents:
40775
diff
changeset
|
53 ... print(obj.attr1) |
|
22760d53d4da
Fix a bunch of doctests with the -d option of refactor.py.
Guido van Rossum <guido@python.org>
parents:
40775
diff
changeset
|
54 ... print(obj.attr2) |
|
22760d53d4da
Fix a bunch of doctests with the -d option of refactor.py.
Guido van Rossum <guido@python.org>
parents:
40775
diff
changeset
|
55 ... print(obj.attr3) |
| 35742 | 56 |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
57 >>> dump(attrs.__code__) |
| 35742 | 58 name: attrs |
| 59 argcount: 1 | |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
60 kwonlyargcount: 0 |
|
40788
e9a6234b26af
* Remove PRINT_ITEM(_TO), PRINT_NEWLINE(_TO) opcodes.
Georg Brandl <georg@python.org>
parents:
40785
diff
changeset
|
61 names: ('print', 'attr1', 'attr2', 'attr3') |
| 35742 | 62 varnames: ('obj',) |
| 63 cellvars: () | |
| 64 freevars: () | |
| 65 nlocals: 1 | |
| 66 flags: 67 | |
| 67 consts: ('None',) | |
| 68 | |
|
39442
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
69 >>> def optimize_away(): |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
70 ... 'doc string' |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
71 ... 'not a docstring' |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
72 ... 53 |
|
40644
1c26505c1de6
Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents:
40215
diff
changeset
|
73 ... 0x53 |
|
39442
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
74 |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
75 >>> dump(optimize_away.__code__) |
|
39442
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
76 name: optimize_away |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
77 argcount: 0 |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
78 kwonlyargcount: 0 |
|
39442
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
79 names: () |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
80 varnames: () |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
81 cellvars: () |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
82 freevars: () |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
83 nlocals: 0 |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
84 flags: 67 |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
85 consts: ("'doc string'", 'None') |
|
654c380cf8b9
Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents:
36121
diff
changeset
|
86 |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
87 >>> def keywordonly_args(a,b,*,k1): |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
88 ... return a,b,k1 |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
89 ... |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
90 |
|
40910
eaaee785eb86
Change all the function attributes from func_* -> __*__. This gets rid
Neal Norwitz <nnorwitz@gmail.com>
parents:
40788
diff
changeset
|
91 >>> dump(keywordonly_args.__code__) |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
92 name: keywordonly_args |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
93 argcount: 2 |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
94 kwonlyargcount: 1 |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
95 names: () |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
96 varnames: ('a', 'b', 'k1') |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
97 cellvars: () |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
98 freevars: () |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
99 nlocals: 3 |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
100 flags: 67 |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
101 consts: ('None',) |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
102 |
| 35742 | 103 """ |
| 104 | |
|
55372
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
105 import unittest |
|
59705
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
106 import weakref |
|
55372
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
107 import _testcapi |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
108 |
|
59705
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
109 |
| 35742 | 110 def consts(t): |
| 111 """Yield a doctest-safe sequence of object reprs.""" | |
| 112 for elt in t: | |
| 113 r = repr(elt) | |
| 114 if r.startswith("<code object"): | |
| 115 yield "<code object %s>" % elt.co_name | |
| 116 else: | |
| 117 yield r | |
| 118 | |
| 119 def dump(co): | |
| 120 """Print out a text representation of a code object.""" | |
|
40215
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
121 for attr in ["name", "argcount", "kwonlyargcount", "names", "varnames", |
|
1cce0526d9b0
Jiwon Seo's PEP 3102 implementation.
Guido van Rossum <guido@python.org>
parents:
39442
diff
changeset
|
122 "cellvars", "freevars", "nlocals", "flags"]: |
|
40775
4cdf21a0dbbc
Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents:
40644
diff
changeset
|
123 print("%s: %s" % (attr, getattr(co, "co_" + attr))) |
|
4cdf21a0dbbc
Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents:
40644
diff
changeset
|
124 print("consts:", tuple(consts(co.co_consts))) |
| 35742 | 125 |
|
55372
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
126 |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
127 class CodeTest(unittest.TestCase): |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
128 |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
129 def test_newempty(self): |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
130 co = _testcapi.code_newempty("filename", "funcname", 15) |
|
66310
9fe76c26ea9f
#9424: Replace deprecated assert* methods in the Python test suite.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
59705
diff
changeset
|
131 self.assertEqual(co.co_filename, "filename") |
|
9fe76c26ea9f
#9424: Replace deprecated assert* methods in the Python test suite.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
59705
diff
changeset
|
132 self.assertEqual(co.co_name, "funcname") |
|
9fe76c26ea9f
#9424: Replace deprecated assert* methods in the Python test suite.
Ezio Melotti <ezio.melotti@gmail.com>
parents:
59705
diff
changeset
|
133 self.assertEqual(co.co_firstlineno, 15) |
|
55372
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
134 |
|
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
135 |
|
59705
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
136 class CodeWeakRefTest(unittest.TestCase): |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
137 |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
138 def test_basic(self): |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
139 # Create a code object in a clean environment so that we know we have |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
140 # the only reference to it left. |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
141 namespace = {} |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
142 exec("def f(): pass", globals(), namespace) |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
143 f = namespace["f"] |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
144 del namespace |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
145 |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
146 self.called = False |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
147 def callback(code): |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
148 self.called = True |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
149 |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
150 # f is now the last reference to the function, and through it, the code |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
151 # object. While we hold it, check that we can create a weakref and |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
152 # deref it. Then delete it, and check that the callback gets called and |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
153 # the reference dies. |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
154 coderef = weakref.ref(f.__code__, callback) |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
155 self.assertTrue(bool(coderef())) |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
156 del f |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
157 self.assertFalse(bool(coderef())) |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
158 self.assertTrue(self.called) |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
159 |
|
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
160 |
| 35742 | 161 def test_main(verbose=None): |
|
55372
79718ee03986
Merged revisions 72487-72488,72879 via svnmerge from
Alexandre Vassalotti <alexandre@peadrop.com>
parents:
47201
diff
changeset
|
162 from test.support import run_doctest, run_unittest |
| 35742 | 163 from test import test_code |
| 164 run_doctest(test_code, verbose) | |
|
59705
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
165 run_unittest(CodeTest, CodeWeakRefTest) |
|
46262
f547ebf02843
Merged revisions 62090-62091,62096,62100,62102,62110-62114 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents:
40910
diff
changeset
|
166 |
|
f547ebf02843
Merged revisions 62090-62091,62096,62100,62102,62110-62114 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents:
40910
diff
changeset
|
167 |
|
59705
eea72b81a23c
Merged revisions 79060 via svnmerge from
Collin Winter <collinw@gmail.com>
parents:
55372
diff
changeset
|
168 if __name__ == "__main__": |
|
46262
f547ebf02843
Merged revisions 62090-62091,62096,62100,62102,62110-62114 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents:
40910
diff
changeset
|
169 test_main() |
