Mercurial > cpython-lru_cache-weakref
annotate Lib/_threading_local.py @ 70817:dd775b1561ba
Fix markup.
| author | Georg Brandl <georg@python.org> |
|---|---|
| date | Tue, 14 Jun 2011 21:09:55 +0200 |
| parents | 3c9232a684ae |
| children |
| 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 | 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 | 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 | 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 |
