gh-128384: Use a context variable for warnings.catch_warnings (gh-130010)

Make `warnings.catch_warnings()` use a context variable for holding
the warning filtering state if the `sys.flags.context_aware_warnings`
flag is set to true.  This makes using the context manager thread-safe in
multi-threaded programs.

Add the `sys.flags.thread_inherit_context` flag.  If true, starting a new
thread with `threading.Thread` will use a copy of the context
from the caller of `Thread.start()`.

Both these flags are set to true by default for the free-threaded build
and false for the default build.

Move the Python implementation of warnings.py into _py_warnings.py.

Make _contextvars a builtin module.

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Neil Schemenauer 2025-04-09 16:18:54 -07:00 committed by GitHub
parent e5237541a0
commit d687900f98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 1851 additions and 960 deletions

View file

@ -152,3 +152,33 @@ to re-enable it in a thread-safe way in the 3.14 release. This overhead is
expected to be reduced in upcoming Python release. We are aiming for an
overhead of 10% or less on the pyperformance suite compared to the default
GIL-enabled build.
Behavioral changes
==================
This section describes CPython behavioural changes with the free-threaded
build.
Context variables
-----------------
In the free-threaded build, the flag :data:`~sys.flags.thread_inherit_context`
is set to true by default which causes threads created with
:class:`threading.Thread` to start with a copy of the
:class:`~contextvars.Context()` of the caller of
:meth:`~threading.Thread.start`. In the default GIL-enabled build, the flag
defaults to false so threads start with an
empty :class:`~contextvars.Context()`.
Warning filters
---------------
In the free-threaded build, the flag :data:`~sys.flags.context_aware_warnings`
is set to true by default. In the default GIL-enabled build, the flag defaults
to false. If the flag is true then the :class:`warnings.catch_warnings`
context manager uses a context variable for warning filters. If the flag is
false then :class:`~warnings.catch_warnings` modifies the global filters list,
which is not thread-safe. See the :mod:`warnings` module for more details.