Skip to content

Commit c28229c

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Sync pre-release CPython main branch from GitHub (2026-06-30)
Summary: Imported python/cpython `3.16.0a0` from upstream rev [`5717518`](https://www.github.com/python/cpython/commit/5717518fb3ed6f34716683e08ec372267d871d21) (committed 2026-06-30 00:05:02+00:00). # Commit Info - Base: (`3.16.0a0`) - [`7d128e3`](https://www.github.com/python/cpython/commit/7d128e319f3730e776a9161a4b5e9de95c802eaf) (commit date: 2026-06-29 02:04:10+00:00) - Imported: (`3.16.0a0`) - [`5717518`](https://www.github.com/python/cpython/commit/5717518fb3ed6f34716683e08ec372267d871d21) (commit date: 2026-06-30 00:05:02+00:00) # Noteworthy file changes - Test files (1 added) - Low-signal files (15 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GN5N6CvpQf1ilV8EAAY5FQ0DcSY5br0LAAAz Differential Revision: D110143618 fbshipit-source-id: 375411414e768ad3811bdbf9f871bb2ec2ec09fb
1 parent 5da95b2 commit c28229c

57 files changed

Lines changed: 3317 additions & 1330 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Doc/c-api/threads.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,61 @@ a thread state that was previously attached for the current thread.
242242
.. seealso::
243243
:pep:`788`
244244

245+
.. _c-api-reuse-thread-state:
246+
247+
Reusing a thread state across repeated calls
248+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
249+
250+
Creating and destroying a :c:type:`PyThreadState` is not free, and is more
251+
expensive on a :term:`free-threaded build`. A foreign thread that calls into
252+
the interpreter many times -- for example, a worker thread in a native thread
253+
pool -- should avoid creating a fresh thread state on every entry and
254+
destroying it on every exit. Instead, set up one thread state when the thread
255+
starts (or lazily on its first call into Python), attach and detach it around
256+
each call, and tear it down once when the thread exits.
257+
258+
Manage the thread state explicitly with :c:func:`PyThreadState_New`, attaching
259+
and detaching it with :c:func:`PyEval_RestoreThread` and
260+
:c:func:`PyEval_SaveThread`. This happens in three distinct phases, at
261+
different points in the thread's life.
262+
263+
When the thread starts, create one thread state for it. ``interp`` is the
264+
target interpreter, captured by the code that created this thread while it held
265+
an attached thread state (for example via :c:func:`PyInterpreterState_Get`)::
266+
267+
PyThreadState *tstate = PyThreadState_New(interp);
268+
269+
Then, on each call into Python -- which may happen many times over the thread's
270+
life -- attach the thread state, make the Python C API calls that require it,
271+
and detach again so the thread does not hold the GIL while off doing non-Python
272+
work::
273+
274+
PyEval_RestoreThread(tstate);
275+
result = CallSomeFunction(); /* your Python C API calls go here */
276+
PyEval_SaveThread();
277+
278+
When the thread is finished calling into Python, destroy the thread state once::
279+
280+
PyEval_RestoreThread(tstate);
281+
PyThreadState_Clear(tstate);
282+
PyThreadState_DeleteCurrent();
283+
284+
The general-purpose entry points for calling in from a foreign thread --
285+
:c:func:`PyThreadState_Ensure` and the older :c:func:`PyGILState_Ensure` -- do
286+
*not* guarantee a persistent thread state: their thread-state lifetime is
287+
deliberately implementation-defined, so a matched acquire/release pair may
288+
create and destroy a thread state each time. Use :c:func:`PyThreadState_New`,
289+
as shown here, whenever you specifically want to reuse one thread state across
290+
calls.
291+
292+
The code that created the foreign thread must arrange for the shutdown sequence
293+
to run before the thread exits, and before :c:func:`Py_FinalizeEx` is called.
294+
If interpreter finalization begins first, the shutdown
295+
:c:func:`PyEval_RestoreThread` call will hang the thread rather than return (see
296+
:ref:`cautions-regarding-runtime-finalization`). If the thread exits without
297+
running the shutdown sequence, the thread state is leaked for the remainder of
298+
the process.
299+
245300
.. _c-api-attach-detach:
246301

247302
Attaching/detaching thread states

Doc/howto/mro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The Python 2.3 Method Resolution Order
1010
The Method Resolution Order discussed here was *introduced* in Python 2.3,
1111
but it is still used in later versions -- including Python 3.
1212

13-
By `Michele Simionato <https://www.phyast.pitt.edu/~micheles/>`__.
13+
By `Michele Simionato <https://github.com/micheles>`__.
1414

1515
:Abstract:
1616

0 commit comments

Comments
 (0)