annotate Lib/_threading_local.py @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents b2e8dcd15040
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
37825
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
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
37825
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
3 (Note that this module provides a Python version of the threading.local
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
4 class. Depending on the version of Python you're using, there may be a
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
5 faster one available. You should always import the `local` class from
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
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():
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
31 ... items = mydata.__dict__.items()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
32 ... items.sort()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
33 ... log.append(items)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
34 ... mydata.number = 11
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
35 ... log.append(mydata.number)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
36
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
37 >>> import threading
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
38 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
39 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
40 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
41 >>> log
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
42 [[], 11]
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
43
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
44 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
45 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
46
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
47 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
48 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
49
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
50 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
51 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
52 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
53 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
54 came from.
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
55
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
56 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
57
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
58 >>> class MyLocal(local):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
59 ... number = 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
60 ... initialized = False
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
61 ... def __init__(self, **kw):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
62 ... if self.initialized:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
63 ... 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
64 ... self.initialized = True
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
65 ... self.__dict__.update(kw)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
66 ... def squared(self):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
67 ... return self.number ** 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
68
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
69 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
70 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
71 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
72 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
73
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
74 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
75
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
76 >>> mydata = MyLocal(color='red')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
77
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
78 Now we have a default number:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
79
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
80 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
81 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
82
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
83 an initial color:
32736
c3a096bfbd6b Whitespace normalization, via reindent.py.
Tim Peters <tim.peters@gmail.com>
parents: 32686
diff changeset
84
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
85 >>> mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
86 'red'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
87 >>> del mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
88
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
89 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
90
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
91 >>> mydata.squared()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
92 4
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
93
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
94 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
95
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
96 >>> log = []
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
97 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
98 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
99 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
100 >>> log
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
101 [[('color', 'red'), ('initialized', True)], 11]
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
102
32686
9a3b4219bcbe Typo fixes
Andrew M. Kuchling <amk@amk.ca>
parents: 32673
diff changeset
103 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
104
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
105 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
106 2
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
107 >>> mydata.color
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
108 Traceback (most recent call last):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
109 ...
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
110 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
111
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
112 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
113 local. They are shared across threads:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
114
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
115 >>> class MyLocal(local):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
116 ... __slots__ = 'number'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
117
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
118 >>> mydata = MyLocal()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
119 >>> mydata.number = 42
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
120 >>> mydata.color = 'red'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
121
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
122 So, the separate thread:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
123
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
124 >>> thread = threading.Thread(target=f)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
125 >>> thread.start()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
126 >>> thread.join()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
127
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
128 affects what we see:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
129
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
130 >>> mydata.number
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
131 11
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
132
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
133 >>> del mydata
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
134 """
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
135
37825
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
136 __all__ = ["local"]
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
137
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
138 # We need to use objects from the threading module, but the threading
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
139 # module may also want to use our `local` class, if support for locals
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
140 # isn't compiled in to the `thread` module. This creates potential problems
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
141 # with circular imports. For that reason, we don't import `threading`
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
142 # until the bottom of this file (a hack sufficient to worm around the
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
143 # potential problems). Note that almost all platforms do have support for
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
144 # locals in the `thread` module, and there is no circular import problem
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
145 # then, so problems introduced by fiddling the order of imports here won't
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
146 # manifest on most boxes.
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
147
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
148 class _localbase(object):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
149 __slots__ = '_local__key', '_local__args', '_local__lock'
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
150
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
151 def __new__(cls, *args, **kw):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
152 self = object.__new__(cls)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
153 key = '_local__key', 'thread.local.' + str(id(self))
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
154 object.__setattr__(self, '_local__key', key)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
155 object.__setattr__(self, '_local__args', (args, kw))
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
156 object.__setattr__(self, '_local__lock', RLock())
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
157
59030
ea02ece323fe fixes issue #1522237, bad init check in _threading_local
Jack Diederich <jackdied@gmail.com>
parents: 57119
diff changeset
158 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
159 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
160
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
161 # 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
162 # __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
163 # again ourselves.
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
164 dict = object.__getattribute__(self, '__dict__')
47598
c349f9fbc704 give the threading API PEP 8 names
Benjamin Peterson <benjamin@python.org>
parents: 37825
diff changeset
165 current_thread().__dict__[key] = dict
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
166
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
167 return self
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
168
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
169 def _patch(self):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
170 key = object.__getattribute__(self, '_local__key')
47598
c349f9fbc704 give the threading API PEP 8 names
Benjamin Peterson <benjamin@python.org>
parents: 37825
diff changeset
171 d = current_thread().__dict__.get(key)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
172 if d is None:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
173 d = {}
47598
c349f9fbc704 give the threading API PEP 8 names
Benjamin Peterson <benjamin@python.org>
parents: 37825
diff changeset
174 current_thread().__dict__[key] = d
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
175 object.__setattr__(self, '__dict__', d)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
176
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
177 # we have a new instance dict, so call out __init__ if we have
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
178 # one
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
179 cls = type(self)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
180 if cls.__init__ is not object.__init__:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
181 args, kw = object.__getattribute__(self, '_local__args')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
182 cls.__init__(self, *args, **kw)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
183 else:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
184 object.__setattr__(self, '__dict__', d)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
185
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
186 class local(_localbase):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
187
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
188 def __getattribute__(self, name):
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
189 lock = object.__getattribute__(self, '_local__lock')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
190 lock.acquire()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
191 try:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
192 _patch(self)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
193 return object.__getattribute__(self, name)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
194 finally:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
195 lock.release()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
196
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
197 def __setattr__(self, name, value):
64300
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
198 if name == '__dict__':
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
199 raise AttributeError(
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
200 "%r object attribute '__dict__' is read-only"
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
201 % self.__class__.__name__)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
202 lock = object.__getattribute__(self, '_local__lock')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
203 lock.acquire()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
204 try:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
205 _patch(self)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
206 return object.__setattr__(self, name, value)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
207 finally:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
208 lock.release()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
209
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
210 def __delattr__(self, name):
64300
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
211 if name == '__dict__':
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
212 raise AttributeError(
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
213 "%r object attribute '__dict__' is read-only"
b2e8dcd15040 Merged revisions 84344 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 59030
diff changeset
214 % self.__class__.__name__)
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
215 lock = object.__getattribute__(self, '_local__lock')
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
216 lock.acquire()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
217 try:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
218 _patch(self)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
219 return object.__delattr__(self, name)
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
220 finally:
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
221 lock.release()
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
222
37825
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
223 def __del__(self):
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
224 import threading
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
225
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
226 key = object.__getattribute__(self, '_local__key')
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
227
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
228 try:
57119
2ebad3dfcde3 Merged revisions 76117 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 47598
diff changeset
229 # We use the non-locking API since we might already hold the lock
2ebad3dfcde3 Merged revisions 76117 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 47598
diff changeset
230 # (__del__ can be called at any point by the cyclic GC).
2ebad3dfcde3 Merged revisions 76117 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 47598
diff changeset
231 threads = threading._enumerate()
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
232 except:
57119
2ebad3dfcde3 Merged revisions 76117 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 47598
diff changeset
233 # If enumerating the current threads fails, as it seems to do
2ebad3dfcde3 Merged revisions 76117 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 47598
diff changeset
234 # during shutdown, we'll skip cleanup under the assumption
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
235 # that there is nothing to clean up.
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
236 return
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
237
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
238 for thread in threads:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
239 try:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
240 __dict__ = thread.__dict__
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
241 except AttributeError:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
242 # Thread is dying, rest in peace.
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
243 continue
32673
97768d87394a Implemented thread-local data as proposed on python-dev:
Jim Fulton <jim@zope.com>
parents:
diff changeset
244
37809
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
245 if key in __dict__:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
246 try:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
247 del __dict__[key]
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
248 except KeyError:
086d8434c7f7 local.__del__(): This didn't actually do anything, because of too
Tim Peters <tim.peters@gmail.com>
parents: 35941
diff changeset
249 pass # didn't have anything in this thread
37825
fc5897418f31 Finally figured out why this module did its imports at the
Tim Peters <tim.peters@gmail.com>
parents: 37809
diff changeset
250
47598
c349f9fbc704 give the threading API PEP 8 names
Benjamin Peterson <benjamin@python.org>
parents: 37825
diff changeset
251 from threading import current_thread, RLock