aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/threading.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/threading.py')
-rw-r--r--Lib/threading.py24
1 files changed, 22 insertions, 2 deletions
diff --git a/Lib/threading.py b/Lib/threading.py
index 0dc1d324c98..c4cc4dd2b00 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -3,6 +3,7 @@
import os as _os
import sys as _sys
import _thread
+import _contextvars
from time import monotonic as _time
from _weakrefset import WeakSet
@@ -876,7 +877,7 @@ class Thread:
_initialized = False
def __init__(self, group=None, target=None, name=None,
- args=(), kwargs=None, *, daemon=None):
+ args=(), kwargs=None, *, daemon=None, context=None):
"""This constructor should always be called with keyword arguments. Arguments are:
*group* should be None; reserved for future extension when a ThreadGroup
@@ -893,6 +894,14 @@ class Thread:
*kwargs* is a dictionary of keyword arguments for the target
invocation. Defaults to {}.
+ *context* is the contextvars.Context value to use for the thread.
+ The default value is None, which means to check
+ sys.flags.thread_inherit_context. If that flag is true, use a copy
+ of the context of the caller. If false, use an empty context. To
+ explicitly start with an empty context, pass a new instance of
+ contextvars.Context(). To explicitly start with a copy of the current
+ context, pass the value from contextvars.copy_context().
+
If a subclass overrides the constructor, it must make sure to invoke
the base class constructor (Thread.__init__()) before doing anything
else to the thread.
@@ -922,6 +931,7 @@ class Thread:
self._daemonic = daemon
else:
self._daemonic = current_thread().daemon
+ self._context = context
self._ident = None
if _HAVE_THREAD_NATIVE_ID:
self._native_id = None
@@ -977,6 +987,16 @@ class Thread:
with _active_limbo_lock:
_limbo[self] = self
+
+ if self._context is None:
+ # No context provided
+ if _sys.flags.thread_inherit_context:
+ # start with a copy of the context of the caller
+ self._context = _contextvars.copy_context()
+ else:
+ # start with an empty context
+ self._context = _contextvars.Context()
+
try:
# Start joinable thread
_start_joinable_thread(self._bootstrap, handle=self._handle,
@@ -1056,7 +1076,7 @@ class Thread:
_sys.setprofile(_profile_hook)
try:
- self.run()
+ self._context.run(self.run)
except:
self._invoke_excepthook(self)
finally: