API Reference
All public objects are importable from the top-level extracontext package.
ContextLocal
The main entry point. A factory that returns either a NativeContextLocal or PyContextLocal instance depending on the backend argument.
extracontext.ContextLocal
Source code in extracontext/base.py
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
ContextMap
A ContextLocal subclass implementing collections.abc.MutableMapping, providing dictionary-style access alongside attribute access.
extracontext.ContextMap
Bases: MutableMapping, ContextLocal
Works the same as PyContextLocal, but uses the mapping interface instead of dealing with instance attributes.
Ideal, as for most map uses, when the keys depend on data rather than hardcoded state variables
Source code in extracontext/mapping.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | |
ContextPreservingExecutor
A concurrent.futures.ThreadPoolExecutor subclass that propagates the current context into worker threads.
extracontext.ContextPreservingExecutor
Bases: ThreadPoolExecutor
Drop in context preserving replacement to concurrent.futures.ThreadPoolExecutor
This class adds a missing functionality to asynchorous coding in Python, in which separate tasks will naturally each have their own context with distinct contextvars (either native stdlib scalar contextvars or extracontext.ContextLocal namespaces): when calling a blocking function with "run_in_executor", the context is zeroed-out in the function executed in any of the worker threads.
By simply instantiating this class for an Executor, the called
functions will run in a copy of the same context that was in use
by the callee - which means one is free to use await loop.run_in_executor
calls and have the target function still see the current context.
Source code in extracontext/executor.py
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
ContextError
Exception raised when a context variable is accessed outside a valid scope.
extracontext.ContextError
Bases: AttributeError
Source code in extracontext/contextlocal.py
34 35 | |
NativeContextLocal
The default backend implementation, built on stdlib contextvars.ContextVar.
extracontext.NativeContextLocal
Bases: ContextLocal
Uses th native contextvar module in the stdlib (PEP 567) to provide a context-local namespace in the way threading.local works for threads.
Assignements and reading from the namespace
should work naturally with no need to call get and set methods.
A new contextvar variable is created in the current (contextvars) context for each attribute acessed on this namespace.
Also, attributes prefixed with a single "et" are intended for internal use and will not be namespaced contextvars.
In contrast to the pure-Python implementation there are
some limitations,such as the impossibility to work
in as a contextmanager (Python with block),.
[Work In Progress]
Source code in extracontext/contextlocal_native.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | |
PyContextLocal
The pure-Python backend implementation, using frame introspection.
extracontext.PyContextLocal
Bases: ContextLocal
Creates a namespace object whose attributes can keep individual and distinct values for the same key for code running in parallel - either in asyncio tasks, or threads.
The bennefits are the same one gets by using contextvars.ContextVar from the stdlib as specified on PEP 567. However extracontext.ContextLocal is designed to be easier and more convenient to use - as a single instance can hold values for several keys, just as happens with threading.local objects. And no special getter and setter methods are needed to retrieve the unique value stored in the current context: normal attribute access and assignment works transparently.
Internally, the current implementation uses a completly different way to keep distinct states where needed: the "locals" mapping for each execution frame is used as storage for the unique values in an async task context, or in a thread. Although not recomended up to now, read/write access to non-local-variables in the "locals" mapping is specified on PEP 558. While that PEP is not final, it is clear in its texts that the capability of using "locals" as a mapping to convey data will be kept and made official.
References to the frames containing context data is kept using weakreferences, so when a Frame ends up execution, its contents are deleted normally, with no risks of frame data hanging around due to PyContextLocal data.
Source code in extracontext/contextlocal.py
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |