| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Context variables created this way will automatically be inherited by the context for new threads, regardless of the setting of `thread_inherit_context`.
Documentation build overview18 files changed · ± 18 modified ± Modified |
Sorry, something went wrong.
|
Another option would be to add a thread_inheritable keyword to ContextVar. This avoids having to come up with a good class-method name and also allows querying of the instance attribute. Not sure why that would be useful but a keyword arg seems like the comman and straightforward way to do this. Example library code that wants to detect support: # logic to fallback to regular ContextVar
if hasattr(ContextVar, "thread_inheritable"):
var = ContextVar("var", thread_inheritable=True)
else:
var = ContextVar("var")
# logic to fallback to global binding
if hasattr(ContextVar, "thread_inheritable"):
# Context-local and inherited by new threads.
def _new_var(name, **kwargs):
return ContextVar(name, thread_inheritable=True, **kwargs)
elif getattr(sys.flags, "thread_inherit_context", False):
# Threads inherit the whole context, so an ordinary
# context variable is inherited too.
_new_var = ContextVar
else:
# Keep the library's historical global semantics.
_new_var = _GlobalVar |
Sorry, something went wrong.
|
Using a keyword has the problem that you could pass thread_inheritable=False. Should that be allowed or maybe it should just raise an error? Using a class-method avoids this concern. |
Sorry, something went wrong.
I actually think this is useful, if you make thread_inheritable=None the default (current False) and then make thread_inheritable=False mean "never inherited AND exempt from the deprecation-warning snapshot". That gives libraries like asgiref the ability to opt out of the deprecation if they explicitly want the old behavior. |
Sorry, something went wrong.
|
I switched this back to draft. Given discussion on Discourse, I think we should have the tri-value thread_inheritable keyword. This needs some more discussion to make sure we get the API correct. |
Sorry, something went wrong.
Use a keyword arg so that `ContextVar(thread_inheritable=False)` is supported. The default is `thread_inheritable=None`, which means to use the value of `thread_inherit_context`. This allows libraries to explicitly specify if they want a variable to be inherited by new threads. Add C function `PyContextVar_NewWithFlags` for creating context variables which override automatic thread context inheritance.
| Back | FazBrowse Home | New Git URL |
Summary
Add the keyword-only thread_inheritable parameter to contextvars.ContextVar to control automatic inheritance of individual variable bindings by new threading.Thread instances:
The policy is exposed through the read-only ContextVar.thread_inheritable attribute.
This gives libraries per-variable control between inheriting no context and inheriting the entire context. In particular, libraries can migrate global state to context-local state while preserving inheritance by new threads, without requiring applications to change a process-wide flag. Variables can also be excluded when the flag is enabled.
Behavior
The C API adds PyContextVar_NewWithFlags() with Py_CONTEXTVAR_INHERIT_THREAD_DEFAULT, Py_CONTEXTVAR_INHERIT_THREAD_ALWAYS, and Py_CONTEXTVAR_INHERIT_THREAD_NEVER.
Implementation
Each Context maintains a second HAMT containing exactly the bindings selected for implicit thread inheritance. This redundant subset is kept synchronized by ContextVar.set() and reset() according to the interpreter-wide flag and each variable's immutable policy.
Thread.start() uses the private _contextvars._new_thread_context() factory to initialize the child directly from this subset. Because HAMTs are immutable, the subset can be shared with the child without scanning or copying bindings, so startup cost is independent of the number of bound variables.
ContextVar gains an internal three-state inheritance policy. PyContext remains publicly opaque, so the additional field does not affect the public C API layout.