annotate Lib/test/test_frame.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 89ce323357db
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
85047
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
1 import gc
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
2 import sys
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
3 import unittest
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
4 import weakref
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
5
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
6 from test import support
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
7
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
8
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
9 class ClearTest(unittest.TestCase):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
10 """
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
11 Tests for frame.clear().
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
12 """
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
13
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
14 def inner(self, x=5, **kwargs):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
15 1/0
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
16
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
17 def outer(self, **kwargs):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
18 try:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
19 self.inner(**kwargs)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
20 except ZeroDivisionError as e:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
21 exc = e
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
22 return exc
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
23
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
24 def clear_traceback_frames(self, tb):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
25 """
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
26 Clear all frames in a traceback.
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
27 """
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
28 while tb is not None:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
29 tb.tb_frame.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
30 tb = tb.tb_next
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
31
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
32 def test_clear_locals(self):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
33 class C:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
34 pass
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
35 c = C()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
36 wr = weakref.ref(c)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
37 exc = self.outer(c=c)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
38 del c
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
39 support.gc_collect()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
40 # A reference to c is held through the frames
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
41 self.assertIsNot(None, wr())
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
42 self.clear_traceback_frames(exc.__traceback__)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
43 support.gc_collect()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
44 # The reference was released by .clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
45 self.assertIs(None, wr())
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
46
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
47 def test_clear_generator(self):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
48 endly = False
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
49 def g():
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
50 nonlocal endly
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
51 try:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
52 yield
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
53 inner()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
54 finally:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
55 endly = True
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
56 gen = g()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
57 next(gen)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
58 self.assertFalse(endly)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
59 # Clearing the frame closes the generator
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
60 gen.gi_frame.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
61 self.assertTrue(endly)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
62
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
63 def test_clear_executing(self):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
64 # Attempting to clear an executing frame is forbidden.
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
65 try:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
66 1/0
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
67 except ZeroDivisionError as e:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
68 f = e.__traceback__.tb_frame
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
69 with self.assertRaises(RuntimeError):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
70 f.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
71 with self.assertRaises(RuntimeError):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
72 f.f_back.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
73
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
74 def test_clear_executing_generator(self):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
75 # Attempting to clear an executing generator frame is forbidden.
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
76 endly = False
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
77 def g():
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
78 nonlocal endly
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
79 try:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
80 1/0
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
81 except ZeroDivisionError as e:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
82 f = e.__traceback__.tb_frame
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
83 with self.assertRaises(RuntimeError):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
84 f.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
85 with self.assertRaises(RuntimeError):
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
86 f.f_back.clear()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
87 yield f
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
88 finally:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
89 endly = True
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
90 gen = g()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
91 f = next(gen)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
92 self.assertFalse(endly)
85059
34e1ecb8edd2 Issue #18666: improve test_frame a bit. Patch by Vajrasky Kok.
Antoine Pitrou <solipsis@pitrou.net>
parents: 85047
diff changeset
93 # Clearing the frame closes the generator
34e1ecb8edd2 Issue #18666: improve test_frame a bit. Patch by Vajrasky Kok.
Antoine Pitrou <solipsis@pitrou.net>
parents: 85047
diff changeset
94 f.clear()
34e1ecb8edd2 Issue #18666: improve test_frame a bit. Patch by Vajrasky Kok.
Antoine Pitrou <solipsis@pitrou.net>
parents: 85047
diff changeset
95 self.assertTrue(endly)
85047
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
96
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
97 @support.cpython_only
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
98 def test_clear_refcycles(self):
85060
89ce323357db Issue #18665: fix typos. Patch by Vajrasky Kok.
Antoine Pitrou <solipsis@pitrou.net>
parents: 85059
diff changeset
99 # .clear() doesn't leave any refcycle behind
85047
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
100 with support.disable_gc():
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
101 class C:
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
102 pass
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
103 c = C()
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
104 wr = weakref.ref(c)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
105 exc = self.outer(c=c)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
106 del c
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
107 self.assertIsNot(None, wr())
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
108 self.clear_traceback_frames(exc.__traceback__)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
109 self.assertIs(None, wr())
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
110
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
111
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
112 def test_main():
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
113 support.run_unittest(__name__)
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
114
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
115 if __name__ == "__main__":
438cdc97d8ee Followup to 862ab99ab570: I forgot to add the magnificent test_frame.py.
Antoine Pitrou <solipsis@pitrou.net>
parents:
diff changeset
116 test_main()