@@ -234,26 +234,15 @@ Rationale
234234This PEP includes several new APIs that intend to fix all of the issues stated
235235above.
236236
237- Bikeshedding and the ``PyThreadState `` namespace
238- ------------------------------------------------
239-
240- To solve the issue with "GIL" terminology, the new functions described by this
241- PEP intended as replacements for ``PyGILState `` will go under the existing
242- ``PyThreadState `` namespace. In Python 3.14, the documentation has been
243- updated to switch over to terms like
244- :term: `"attached thread state" <attached thread state> ` instead of
245- :term: `"global interpreter lock" <global interpreter lock> `, so this namespace
246- seems to fit well for the functions in this PEP.
247-
248- Full deprecation of old APIs
249- ----------------------------
237+ Replacing the old APIs
238+ ----------------------
250239
251240As made clear in Motivation _, ``PyGILState `` is already pretty buggy, and
252241even if it was magically fixed, the current behavior of hanging the thread is
253- beyond repair. As such , this PEP intends to completely deprecate the existing
254- ``PyGILState `` APIs. However, even if this PEP is rejected, all of the APIs
255- can be replaced with more correct ``PyThreadState `` functions in the current
256- C API:
242+ beyond repair. In turn , this PEP intends to completely deprecate the existing
243+ ``PyGILState `` APIs and provide better alternatives . However, even if this PEP
244+ is rejected, all of the APIs can be replaced with more correct ``PyThreadState ``
245+ functions in the current C API:
257246
258247- :c:func: `PyGILState_Ensure `: :c:func: `PyThreadState_Swap ` / :c:func: `PyThreadState_New `
259248- :c:func: `PyGILState_Release `: :c:func: `PyThreadState_Clear ` / :c:func: `PyThreadState_Delete `
@@ -263,12 +252,23 @@ C API:
263252A light layer of magic
264253----------------------
265254
266- The APIs proposed by this PEP intentionally have a layer of "magic" that is
267- kept from the user and offloads complexity onto CPython maintainers . This is
268- done primarily to help ease the transition from ``PyGILState `` for existing
255+ The APIs proposed by this PEP intentionally have a layer of abstraction that is
256+ hidden from the user and offloads complexity onto CPython. This is done
257+ primarily to help ease the transition from ``PyGILState `` for existing
269258codebases, and for ease-of-use to those who provide wrappers the C API, such
270259as Cython or PyO3. See also :ref: `pep-788-activate-deactivate-instead `.
271260
261+ Bikeshedding and the ``PyThreadState `` namespace
262+ ------------------------------------------------
263+
264+ To solve the issue with "GIL" terminology, the new functions described by this
265+ PEP intended as replacements for ``PyGILState `` will go under the existing
266+ ``PyThreadState `` namespace. In Python 3.14, the documentation has been
267+ updated to switch over to terms like
268+ :term: `"attached thread state" <attached thread state> ` instead of
269+ :term: `"global interpreter lock" <global interpreter lock> `, so this namespace
270+ seems to fit well for this PEP.
271+
272272Specification
273273=============
274274
@@ -297,12 +297,14 @@ prevent the interpreter from finalizing.
297297 This function is generally meant to be used in tandem with
298298 :c:func:`PyThreadState_Ensure`.
299299
300- The caller must have an :term:`attached thread state`.
300+ The caller must have an :term:`attached thread state`, and cannot return
301+ ``NULL``. Failures are always a fatal error.
301302
302303
303304.. c:function:: void PyInterpreterState_Release(PyInterpreterState *interp)
304305
305- Decrement the reference count of the interpreter.
306+ Decrement the reference count of the interpreter, as was incremented by
307+ :c:func: `PyInterpreterState_Hold `.
306308
307309 This function cannot fail, other than with a fatal error. The caller must
308310 have an :term: `attached thread state ` for *interp *.
@@ -352,18 +354,20 @@ replace :c:func:`PyGILState_Ensure` and :c:func:`PyGILState_Release`.
352354
353355.. c:function:: int PyThreadState_Ensure(PyInterpreterState *interp)
354356
355- Ensure that the thread has an :term: `attached thread state ` for *interp *, and
356- thus can safely invoke that interpreter. It is OK to call this function if
357- the thread already has an attached thread state, as long as there is a
358- subsequent call to :c:func: `PyThreadState_Release ` that matches this one.
357+ Ensure that the thread has an :term: `attached thread state ` for *interp *,
358+ and thus can safely invoke that interpreter. It is OK to call this
359+ function if the thread already has an attached thread state, as long as
360+ there is a subsequent call to :c:func: `PyThreadState_Release ` that matches
361+ this one.
359362
360- The interpreter's *interp * reference count is decremented by one. As such, *interp *
361- should have been acquired by :c:func: `PyInterpreterState_Hold `.
363+ The interpreter's *interp * reference count is decremented by one.
364+ As such, *interp * should have been acquired by
365+ :c:func: `PyInterpreterState_Hold `.
362366
363367 Thread states created by this function are non-daemon by default. See
364368 :c:func: `PyThreadState_SetDaemon `. If the calling thread already has an
365- :term: `attached thread state ` that matches *interp *, then this function will
366- simply mark the existing thread state as non-daemon and return. It will
369+ :term: `attached thread state ` that matches *interp *, then this function
370+ will mark the existing thread state as non-daemon and return. It will
367371 be restored to its prior daemon status upon the next
368372 :c:func: `PyThreadState_Release ` call.
369373
@@ -594,24 +598,26 @@ This was ultimately rejected for two reasons:
594598 for code-generators like Cython to use, as there isn't any additional
595599 complexity with tracking :c:type: `PyThreadState ` pointers around.
596600
597- Open Issues
598- ===========
601+ Using `` PyStatus `` for the return value of :c:func: ` PyThreadState_Ensure `
602+ -------------------------------------------------------------------------
599603
600- Use ``PyStatus `` for the return value of :c:func: `PyThreadState_Ensure `?
601- ------------------------------------------------------------------------
604+ In prior iterations of this API, :c:func: `PyThreadState_Ensure ` returned a
605+ :c:type: `PyStatus ` instead of an integer to denote failures, which had the
606+ benefit of providing an error message.
602607
603- :c:func: `PyThreadState_Ensure ` returns an integer to return failures, but some
604- iterations have suggested the use of :c:type: `PyStatus ` to denote failure,
605- which has the benefit of providing an error message. The main hesitation for
606- switching to ``PyStatus `` is that it's more difficult to use, as the
607- ``PyStatus `` has to be stored and checked, whereas a simple integer can simply
608- be used inline with an ``if `` clause.
609-
610- Additionally, it's
611- `not clear <https://discuss.python.org/t/83959/7 >`_
608+ This was rejected because it's `not clear <https://discuss.python.org/t/83959/7 >`_
612609that an error message would be all that useful; all the conceived use-cases
613- for this API wouldn't really care about a message indicating why Python can't
614- be invoked.
610+ for this API wouldn't really care about a message indicating why Python
611+ can't be invoked. As such, the API would only be needlessly harder to use,
612+ which in turn would hurt the transition from :c:func: `PyGILState_Ensure `.
613+
614+ In addition, :c:type: `PyStatus ` isn't commonly used in the C API. A few
615+ functions related to interpreter initialization use it (simply because they
616+ can't raise exceptions), and :c:func:`PyThreadState_Ensure` does not fall
617+ under that category.
618+
619+ Open Issues
620+ ===========
615621
616622When should the legacy APIs be removed?
617623---------------------------------------
0 commit comments