annotate Lib/_threading_local.py @ 84007:dbfbdf2b5c19 3.3

Fix #17967: For ftp urls CWD to target instead of hopping to each directory towards target. This fixes a bug where target is accessible, but parent directories are restricted.
author Senthil Kumaran <senthil@uthcode.com>
date Sat, 01 Jun 2013 08:27:06 -0700
parents 3c9232a684ae
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
1 """Thread-local objects.
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
2
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
3 (Note that this module provides a Python version of the threading.local
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
4 class. Depending on the version of Python you're using, there may be a
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
5 faster one available. You should always import the `local` class from
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
6 `threading`.)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
7
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
8 Thread-local objects support the management of thread-local data.
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
9 If you have data that you want to be local to a thread, simply create
32686
9a3b4219bcbe Typo fixes
Andrew M. Kuchling <amk@amk.ca>
parents: 32673
diff changeset
10 a thread-local object and use its attributes:
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
11
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
12 >>> mydata = local()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
13 >>> mydata.number = 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
14 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
15 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
16
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
17 You can also access the local-object's dictionary:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
18
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
19 >>> mydata.__dict__
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
20 {'number': 42}
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
21 >>> mydata.__dict__.setdefault('widgets', [])
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
22 []
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
23 >>> mydata.widgets
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
24 []
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
25
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
26 What's important about thread-local objects is that their data are
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
27 local to a thread. If we access the data in a different thread:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
28
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
29 >>> log = []
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
30 >>> def f():
40809
f340cb045bf9 - PEP 3106: dict.iterkeys(), .iteritems(), .itervalues() are now gone;
Guido van Rossum <guido@python.org>
parents: 37879
diff changeset
31 ... items = sorted(mydata.__dict__.items())
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
32 ... log.append(items)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
33 ... mydata.number = 11
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
34 ... log.append(mydata.number)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
35
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
36 >>> import threading
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
37 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
38 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
39 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
40 >>> log
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
41 [[], 11]
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
43 we get different data. Furthermore, changes made in the other thread
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
44 don't affect data seen in this thread:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
45
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
46 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
47 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
48
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
49 Of course, values you get from a local object, including a __dict__
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
50 attribute, are for whatever thread was current at the time the
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
51 attribute was read. For that reason, you generally don't want to save
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
52 these values across threads, as they apply only to the thread they
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
53 came from.
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
54
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
55 You can create custom local objects by subclassing the local class:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
56
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
57 >>> class MyLocal(local):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
58 ... number = 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
59 ... initialized = False
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
60 ... def __init__(self, **kw):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
61 ... if self.initialized:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
62 ... raise SystemError('__init__ called too many times')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
63 ... self.initialized = True
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
64 ... self.__dict__.update(kw)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
65 ... def squared(self):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
66 ... return self.number ** 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
67
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
68 This can be useful to support default values, methods and
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
69 initialization. Note that if you define an __init__ method, it will be
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
70 called each time the local object is used in a separate thread. This
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
71 is necessary to initialize each thread's dictionary.
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
72
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
73 Now if we create a local object:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
74
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
75 >>> mydata = MyLocal(color='red')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
76
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
77 Now we have a default number:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
78
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
79 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
80 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
81
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
82 an initial color:
32736
c3a096bfbd6b Whitespace normalization, via reindent.py.
Tim Peters <tim.peters@gmail.com>
parents: 32686
diff changeset
83
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
84 >>> mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
85 'red'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
86 >>> del mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
87
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
88 And a method that operates on the data:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
89
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
90 >>> mydata.squared()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
91 4
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
92
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
93 As before, we can access the data in a separate thread:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
94
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
95 >>> log = []
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
96 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
97 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
98 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
99 >>> log
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
100 [[('color', 'red'), ('initialized', True)], 11]
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
101
32686
9a3b4219bcbe Typo fixes
Andrew M. Kuchling <amk@amk.ca>
parents: 32673
diff changeset
102 without affecting this thread's data:
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
103
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
104 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
105 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
106 >>> mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
107 Traceback (most recent call last):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
108 ...
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
109 AttributeError: 'MyLocal' object has no attribute 'color'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
110
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
111 Note that subclasses can define slots, but they are not thread
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
112 local. They are shared across threads:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
113
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
114 >>> class MyLocal(local):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
115 ... __slots__ = 'number'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
116
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
117 >>> mydata = MyLocal()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
118 >>> mydata.number = 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
119 >>> mydata.color = 'red'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
120
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
121 So, the separate thread:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
122
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
123 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
124 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
125 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
126
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
127 affects what we see:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
128
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
129 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
130 11
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
131
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
132 >>> del mydata
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
133 """
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
134
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
135 from weakref import ref
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
136 from contextlib import contextmanager
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
137
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
138 __all__ = ["local"]
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
139
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
140 # We need to use objects from the threading module, but the threading
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
141 # module may also want to use our `local` class, if support for locals
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
142 # isn't compiled in to the `thread` module. This creates potential problems
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
143 # with circular imports. For that reason, we don't import `threading`
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
144 # until the bottom of this file (a hack sufficient to worm around the
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
145 # potential problems). Note that all platforms on CPython do have support
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
146 # for locals in the `thread` module, and there is no circular import problem
37879
f731859e9b3b Merge p3yk branch with the trunk up to revision 45595. This breaks a fair
Thomas Wouters <thomas@python.org>
parents: 35941
diff changeset
147 # then, so problems introduced by fiddling the order of imports here won't
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
148 # manifest.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
149
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
150 class _localimpl:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
151 """A class managing thread-local dicts"""
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
152 __slots__ = 'key', 'dicts', 'localargs', 'locallock', '__weakref__'
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
153
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
154 def __init__(self):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
155 # The key used in the Thread objects' attribute dicts.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
156 # We keep it a string for speed but make it unlikely to clash with
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
157 # a "real" attribute.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
158 self.key = '_threading_local._localimpl.' + str(id(self))
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
159 # { id(Thread) -> (ref(Thread), thread-local dict) }
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
160 self.dicts = {}
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
161
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
162 def get_dict(self):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
163 """Return the dict for the current thread. Raises KeyError if none
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
164 defined."""
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
165 thread = current_thread()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
166 return self.dicts[id(thread)][1]
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
167
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
168 def create_dict(self):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
169 """Create a new dict for the current thread, and return it."""
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
170 localdict = {}
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
171 key = self.key
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
172 thread = current_thread()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
173 idt = id(thread)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
174 def local_deleted(_, key=key):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
175 # When the localimpl is deleted, remove the thread attribute.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
176 thread = wrthread()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
177 if thread is not None:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
178 del thread.__dict__[key]
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
179 def thread_deleted(_, idt=idt):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
180 # When the thread is deleted, remove the local dict.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
181 # Note that this is suboptimal if the thread object gets
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
182 # caught in a reference loop. We would like to be called
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
183 # as soon as the OS-level thread ends instead.
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
184 local = wrlocal()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
185 if local is not None:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
186 dct = local.dicts.pop(idt)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
187 wrlocal = ref(self, local_deleted)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
188 wrthread = ref(thread, thread_deleted)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
189 thread.__dict__[key] = wrlocal
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
190 self.dicts[idt] = wrthread, localdict
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
191 return localdict
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
192
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
193
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
194 @contextmanager
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
195 def _patch(self):
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
196 impl = object.__getattribute__(self, '_local__impl')
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
197 try:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
198 dct = impl.get_dict()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
199 except KeyError:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
200 dct = impl.create_dict()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
201 args, kw = impl.localargs
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
202 self.__init__(*args, **kw)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
203 with impl.locallock:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
204 object.__setattr__(self, '__dict__', dct)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
205 yield
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
206
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
207
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
208 class local:
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
209 __slots__ = '_local__impl', '__dict__'
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
210
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
211 def __new__(cls, *args, **kw):
59031
ef732c3db63d fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 57121
diff changeset
212 if (args or kw) and (cls.__init__ is object.__init__):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
213 raise TypeError("Initialization arguments are not supported")
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
214 self = object.__new__(cls)
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
215 impl = _localimpl()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
216 impl.localargs = (args, kw)
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
217 impl.locallock = RLock()
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
218 object.__setattr__(self, '_local__impl', impl)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
219 # We need to create the thread dict in anticipation of
35941
033bb4db5ae8 Fix some comment typos
Neal Norwitz <nnorwitz@gmail.com>
parents: 32736
diff changeset
220 # __init__ being called, to make sure we don't call it
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
221 # again ourselves.
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
222 impl.create_dict()
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
223 return self
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
224
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
225 def __getattribute__(self, name):
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
226 with _patch(self):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
227 return object.__getattribute__(self, name)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
228
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
229 def __setattr__(self, name, value):
64299
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
230 if name == '__dict__':
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
231 raise AttributeError(
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
232 "%r object attribute '__dict__' is read-only"
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
233 % self.__class__.__name__)
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
234 with _patch(self):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
235 return object.__setattr__(self, name, value)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
236
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
237 def __delattr__(self, name):
64299
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
238 if name == '__dict__':
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
239 raise AttributeError(
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
240 "%r object attribute '__dict__' is read-only"
4c978cd3640f Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 57121
diff changeset
241 % self.__class__.__name__)
64543
c2d6f0cf926a Issue #9707: Rewritten reference implementation of threading.local which
Antoine Pitrou <solipsis@pitrou.net>
parents: 64298
diff changeset
242 with _patch(self):
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
243 return object.__delattr__(self, name)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
244
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
245
47615
045f83a1b864 Merged revisions 64125 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 40809
diff changeset
246 from threading import current_thread, RLock