annotate Lib/test/test_threading_local.py @ 79675:c0a2294de787 2.7

Issue #16199: Backport 2to3 typo fix from 3.2.
author Chris Jerdonek <chris.jerdonek@gmail.com>
date Thu, 11 Oct 2012 16:15:46 -0700
parents b36cb4602e21
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
1 import unittest
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
2 from doctest import DocTestSuite
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
3 from test import test_support
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
4 import weakref
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
5 import gc
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
6
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
7 # Modules under test
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
8 _thread = test_support.import_module('thread')
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
9 threading = test_support.import_module('threading')
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
10 import _threading_local
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
11
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
12
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
13 class Weak(object):
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
14 pass
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
15
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
16 def target(local, weaklist):
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
17 weak = Weak()
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
18 local.weak = weak
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
19 weaklist.append(weakref.ref(weak))
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
20
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
21 class BaseLocalTest:
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
22
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
23 def test_local_refs(self):
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
24 self._local_refs(20)
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
25 self._local_refs(50)
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
26 self._local_refs(100)
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
27
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
28 def _local_refs(self, n):
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
29 local = self._local()
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
30 weaklist = []
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
31 for i in range(n):
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
32 t = threading.Thread(target=target, args=(local, weaklist))
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
33 t.start()
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
34 t.join()
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
35 del t
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
36
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
37 gc.collect()
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
38 self.assertEqual(len(weaklist), n)
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
39
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
40 # XXX _threading_local keeps the local of the last stopped thread alive.
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
41 deadlist = [weak for weak in weaklist if weak() is None]
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
42 self.assertIn(len(deadlist), (n-1, n))
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
43
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
44 # Assignment to the same thread local frees it sometimes (!)
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
45 local.someothervar = None
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
46 gc.collect()
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
47 deadlist = [weak for weak in weaklist if weak() is None]
58460
17891566a478 use assert[Not]In where appropriate
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56274
diff changeset
48 self.assertIn(len(deadlist), (n-1, n), (n, len(deadlist)))
44764
52e821418a79 Update for threading.local test.
Christian Heimes <christian@cheimes.de>
parents: 44763
diff changeset
49
47869
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
50 def test_derived(self):
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
51 # Issue 3088: if there is a threads switch inside the __init__
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
52 # of a threading.local derived class, the per-thread dictionary
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
53 # is created but not correctly set on the object.
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
54 # The first member set may be bogus.
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
55 import time
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
56 class Local(self._local):
47869
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
57 def __init__(self):
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
58 time.sleep(0.01)
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
59 local = Local()
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
60
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
61 def f(i):
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
62 local.x = i
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
63 # Simply check that the variable is correctly set
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
64 self.assertEqual(local.x, i)
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
65
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
66 threads= []
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
67 for i in range(10):
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
68 t = threading.Thread(target=f, args=(i,))
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
69 t.start()
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
70 threads.append(t)
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
71
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
72 for t in threads:
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
73 t.join()
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
74
56278
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
75 def test_derived_cycle_dealloc(self):
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
76 # http://bugs.python.org/issue6990
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
77 class Local(self._local):
56278
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
78 pass
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
79 locals = None
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
80 passed = [False]
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
81 e1 = threading.Event()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
82 e2 = threading.Event()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
83
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
84 def f():
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
85 # 1) Involve Local in a cycle
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
86 cycle = [Local()]
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
87 cycle.append(cycle)
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
88 cycle[0].foo = 'bar'
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
89
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
90 # 2) GC the cycle (triggers threadmodule.c::local_clear
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
91 # before local_dealloc)
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
92 del cycle
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
93 gc.collect()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
94 e1.set()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
95 e2.wait()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
96
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
97 # 4) New Locals should be empty
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
98 passed[0] = all(not hasattr(local, 'foo') for local in locals)
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
99
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
100 t = threading.Thread(target=f)
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
101 t.start()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
102 e1.wait()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
103
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
104 # 3) New Locals should recycle the original's address. Creating
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
105 # them in the thread overwrites the thread state and avoids the
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
106 # bug
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
107 locals = [Local() for i in range(10)]
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
108 e2.set()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
109 t.join()
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
110
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
111 self.assertTrue(passed[0])
edd9a5e3cafb #6990: clear threading.local's key only after its thread state is removed:
Philip Jenvey <pjenvey@underboss.org>
parents: 47869
diff changeset
112
59030
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
113 def test_arguments(self):
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
114 # Issue 1522237
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
115 from thread import _local as local
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
116 from _threading_local import local as py_local
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
117
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
118 for cls in (local, py_local):
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
119 class MyLocal(cls):
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
120 def __init__(self, *args, **kwargs):
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
121 pass
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
122
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
123 MyLocal(a=1)
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
124 MyLocal(1)
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
125 self.assertRaises(TypeError, cls, a=1)
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
126 self.assertRaises(TypeError, cls, 1)
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 58460
diff changeset
127
64300
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
128 def _test_one_class(self, c):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
129 self._failed = "No error message set or cleared."
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
130 obj = c()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
131 e1 = threading.Event()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
132 e2 = threading.Event()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
133
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
134 def f1():
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
135 obj.x = 'foo'
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
136 obj.y = 'bar'
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
137 del obj.y
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
138 e1.set()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
139 e2.wait()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
140
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
141 def f2():
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
142 try:
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
143 foo = obj.x
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
144 except AttributeError:
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
145 # This is expected -- we haven't set obj.x in this thread yet!
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
146 self._failed = "" # passed
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
147 else:
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
148 self._failed = ('Incorrectly got value %r from class %r\n' %
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
149 (foo, c))
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
150 sys.stderr.write(self._failed)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
151
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
152 t1 = threading.Thread(target=f1)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
153 t1.start()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
154 e1.wait()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
155 t2 = threading.Thread(target=f2)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
156 t2.start()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
157 t2.join()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
158 # The test is done; just let t1 know it can exit, and wait for it.
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
159 e2.set()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
160 t1.join()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
161
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
162 self.assertFalse(self._failed, self._failed)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
163
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
164 def test_threading_local(self):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
165 self._test_one_class(self._local)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
166
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
167 def test_threading_local_subclass(self):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
168 class LocalSubclass(self._local):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
169 """To test that subclasses behave properly."""
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
170 self._test_one_class(LocalSubclass)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
171
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
172 def _test_dict_attribute(self, cls):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
173 obj = cls()
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
174 obj.x = 5
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
175 self.assertEqual(obj.__dict__, {'x': 5})
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
176 with self.assertRaises(AttributeError):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
177 obj.__dict__ = {}
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
178 with self.assertRaises(AttributeError):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
179 del obj.__dict__
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
180
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
181 def test_dict_attribute(self):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
182 self._test_dict_attribute(self._local)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
183
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
184 def test_dict_attribute_subclass(self):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
185 class LocalSubclass(self._local):
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
186 """To test that subclasses behave properly."""
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
187 self._test_dict_attribute(LocalSubclass)
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 63899
diff changeset
188
47859
8ccb35739a96 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 44764
diff changeset
189
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
190 class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
191 _local = _thread._local
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
192
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
193 # Fails for the pure Python implementation
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
194 def test_cycle_collection(self):
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
195 class X:
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
196 pass
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
197
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
198 x = X()
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
199 x.local = self._local()
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
200 x.local.x = x
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
201 wr = weakref.ref(x)
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
202 del x
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
203 gc.collect()
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
204 self.assertIs(wr(), None)
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
205
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
206 class PyThreadingLocalTest(unittest.TestCase, BaseLocalTest):
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
207 _local = _threading_local.local
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
208
47869
e8bee3097d44 #Issue3088 in-progress: Race condition with instances of classes derived from threading.local:
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 33313
diff changeset
209
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
210 def test_main():
44763
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
211 suite = unittest.TestSuite()
73b5e939e058 Added unit test to verify that threading.local doesn't cause ref leaks. It seems that the thread local storage always keeps the storage of the last stopped thread alive. Can anybody comment on it, please?
Christian Heimes <christian@cheimes.de>
parents: 41554
diff changeset
212 suite.addTest(DocTestSuite('_threading_local'))
63899
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
213 suite.addTest(unittest.makeSuite(ThreadLocalTest))
b65dce5902a2 Merged revisions 83918 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 61046
diff changeset
214 suite.addTest(unittest.makeSuite(PyThreadingLocalTest))
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
215
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
216 try:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
217 from thread import _local
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
218 except ImportError:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
219 pass
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
220 else:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
221 import _threading_local
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
222 local_orig = _threading_local.local
33313
542a5efa4883 setUp and tearDown functions are now passed the test object
Jim Fulton <jim@zope.com>
parents: 32673
diff changeset
223 def setUp(test):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
224 _threading_local.local = _local
33313
542a5efa4883 setUp and tearDown functions are now passed the test object
Jim Fulton <jim@zope.com>
parents: 32673
diff changeset
225 def tearDown(test):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
226 _threading_local.local = local_orig
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
227 suite.addTest(DocTestSuite('_threading_local',
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
228 setUp=setUp, tearDown=tearDown)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
229 )
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
230
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 33313
diff changeset
231 test_support.run_unittest(suite)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
232
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
233 if __name__ == '__main__':
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
234 test_main()