Mercurial > cpython-lru_cache-weakref
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 |
| 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() |
