diff --git a/peps/pep-0803.rst b/peps/pep-0803.rst index cb1643e4343..0f2d8f55020 100644 --- a/peps/pep-0803.rst +++ b/peps/pep-0803.rst @@ -1,5 +1,5 @@ PEP: 803 -Title: Stable ABI for Free-Threaded Builds +Title: "abi3t": Stable ABI for Free-Threaded Builds Author: Petr Viktorin Discussions-To: https://discuss.python.org/t/103628 Status: Draft @@ -7,20 +7,23 @@ Type: Standards Track Requires: 703, 793, 697 Created: 19-Aug-2025 Python-Version: 3.15 -Post-History: `08-Sep-2025 `__ +Post-History: `08-Sep-2025 `__, + `20-Nov-2025 `__, Abstract ======== -Version 3.15 of the Stable ABI will be compatible with both free-threaded and -GIL-enabled builds. -To allow this, the :c:type:`PyObject` internal structure and related APIs -will be removed from version 3.15 of the Limited API, requiring migration to -new API for common tasks like defining modules and most classes. +Add a new variant of the Stable ABI, called “Stable ABI for Free-Threaded +Python” (or ``abi3t`` for short), and a corresponding API limitations. -Binary distributions (wheels) built with Limited API version 3.15 and above -should use the ABI tag ``abi3.abi3t``. +``abi3t`` will be based on the existing Stable ABI (``abi3``), but make the +:c:type:`PyObject` structure opaque. +This will require users to migrate to new API for common tasks like defining +modules and most classes. + +At least initially, extensions built for ``abi3t`` will be compatible with +the existing Stable ABI (``abi3``). Terminology @@ -34,8 +37,10 @@ Motivation ========== The Stable ABI is currently not available for free-threaded builds. -Extensions will fail to build when :c:macro:`Py_LIMITED_API` is defined, -and extensions built for GIL-enabled builds of CPython will fail to load +Extensions will fail to build for a both Limited API and +free-threaded Python (that is, when both :c:macro:`Py_LIMITED_API` and +:c:macro:`Py_GIL_DISABLED` preprocessor macros are defined). +Extensions built for GIL-enabled builds of CPython will fail to load (or crash) on free-threaded builds. In its `acceptance post `__ @@ -48,68 +53,140 @@ This PEP proposes the Stable ABI for free-threading. Background ---------- -Python's Stable ABI, as defined in :pep:`384` and :pep:`652`, provides a way to -compile extension modules that can be loaded on multiple minor versions of the -CPython interpreter. +Python's Stable ABI (``abi3`` for short), as defined in :pep:`384` and +:pep:`652`, provides a way to compile extension modules that can be loaded +on multiple minor versions of the CPython interpreter. Several projects use this to limit the number of :ref:`wheels ` (binary artefacts) that need to be built and distributed for each release, and/or to make it easier to test with pre-release versions of Python. With free-threading builds (:pep:`703`) being on track to eventually become -the default (:pep:`779`), we need a way to make the Stable ABI available +the default (:pep:`779`), we need a way to make a Stable ABI available to those builds. -To build against the Stable ABI, the extension must use a *Limited API*, +To build against a Stable ABI, the extension must use a *Limited API*, that is, only a subset of the functions, structures, etc. that CPython exposes. -Both the Limited API and the Stable ABI are versioned, and building against -Stable ABI 3.X requires using only Limited API 3.X, and yields an extension -that is ABI-compatible with CPython 3.X and *any* later version +Both the Limited API and the current Stable ABI are versioned, and building +against Stable ABI 3.X requires using only Limited API 3.X, and yields an +extension that is ABI-compatible with CPython 3.X and *any* later version (though bugs in CPython sometimes cause incompatibilities in practice). The Limited API is not “stable”: newer versions may remove API that were a part of older versions. -This PEP proposes the most significant such removal to date. + +This PEP proposes additional API limitations, as required to be compatible +with both GIL-enabled and free-threaded builds of CPython. Rationale ========= -The design in this PEP makes several assumptions: +The design in this PEP uses several constraints: + +Separate ABI + The new ABI (``abi3t``) will conceptually be treated as separate from the + existing Stable ABI (``abi3``). -One ABI - A single compiled extension module should support both - free-threaded and GIL-enabled builds. + However, it will be possible to compile a single extension module that + supports both free-threaded and GIL-enabled builds. + This should involve no additional limitations, at least in the initial + implementation, and so it will be preferred over building + ``abi3t``-only extensions. No backwards compatibility now - The new limited API will not support CPython 3.14 and below. + The new stable ABI variant will not support CPython 3.14 and below. Projects that need this support can build separate extensions specifically for the 3.14 free-threaded interpreter, and for older stable ABI versions. However, we won't block the possibility of extending compatibility to - CPython 3.14 and below. + CPython 3.14 and below, and we recommend that package installation tools + prepare for such extensions. See a :ref:`rejected idea ` for how this could work. API changes are OK - The new Limited API may require extension authors to make significant - changes to their code. - Projects that cannot do this (yet) can continue using Limited API 3.14, - which will yield extensions compatible with GIL-enabled builds only. + The new Limited API variant may require extension authors to make + significant changes to their code. + Projects that cannot do this (yet) can continue using the existing Limited + API, and compile separately for GIL-enabled builds + and for specific versions of free-threaded builds. + + +Tag name +-------- -No extra configuration - We do not introduce new “knobs” that influence what API is available - and what the ABI is compatible with. +The tag ``abi3t`` is chosen to reflect the fact that this ABI is similar to +``abi3``, with minimal changes necessary to support free-threading (which +uses the letter ``t`` in existing, version-specific ABI tags like ``cp314t``). Specification ============= +Stable ABI for free-threaded builds +----------------------------------- + +Python will introduce a new stable ABI, called *stable ABI for free-threading +builds*, or ``abi3t`` for short. +As with the current Stable ABI (``abi3``), ``abi3t`` will be versioned +using major (3) and minor versions of Python interpreter. +Extensions built for ``abi3t`` :samp:`3.{x}` will be compatible with +CPython :samp:`3.{x}` and above. + +To build a C/C++ extension for ``abi3t``, the extension will need to only +use *limited API for free-threaded builds*. +Like the existing Limited API, this will be a subset of the general CPython +C API. +Initially, it will also be a subset of the Limited API. +We will strive to keep it as a subset, but will not guarantee this. + +Since ``abi3t`` and ``abi3`` will overlap, it will be possible for a single +compiled extension to support both at once, and thus be compatible with +CPython 3.15+ (both free-threaded and GIL-eanbled builds). +Initially, any extension compiled for ``abi3t`` will be compatible with +``abi3`` as well. + + +Choosing the target ABI +----------------------- + +Users of the C API -- or build tools acting on their behalf, configured by +tool-specific UI -- will select the target ABI using the following macros: + +* ``Py_LIMITED_API=`` (existing): + Compile for ``abi3`` of the given version. +* ``Py_TARGET_ABI3T=`` (proposed here): + Compile for ``abi3t`` of the given version. + +These two macros are functionally very similar. +In hindsight, ``Py_TARGET_ABI3`` (without the ``T``) would be a more fitting +name for :c:macro:`Py_LIMITED_API`. +We keep the existing name for backwards compatibility. + +For ease of use and implementation simplicity, respectively, ``Python.h`` will +set the configuration macros automatically in the following situations: + +* If :samp:`Py_LIMITED_API={v}` and ``Py_GIL_DISABLED`` is set, then + ``Py_TARGET_ABI3T`` will be defined as :samp:`{v}` by default. + (This allows choosing ``abi3t`` by defining the pre-existing macro and + compiling with free-threaded CPython headers. Note that in CPython 3.14, + this case results in a compile-time error.) + +* If :samp:`Py_TARGET_ABI3T={v}` is set, CPython *may* define or redefine + ``Py_LIMITED_API`` as :samp:`{v}`. + (This means that CPython can continue to use the ``Py_LIMITED_API`` macro + internally to select which APIs are available.) + + Opaque PyObject --------------- -Version 3.15 of the Limited API will: +``abi3t`` will initially have a single diffenerce from ``abi3``: the +``PyObject`` structure and APIs that depend on it are not part of ``abi3t``. + +Specifically, when building for ``abi3t``, the CPython headers will: - make the following structures *opaque* (or in C terminology, *incomplete types*): @@ -127,10 +204,12 @@ Version 3.15 of the Limited API will: - :c:macro:`PyObject_VAR_HEAD` - :c:func:`Py_SET_TYPE` -- export the following as functions in the ABI, rather than macros: +In both the regular stable ABI (``abit3`` 3.15+) and the new +``abi3t``, the following will be exported functions (exposed in the ABI) +rather than macros: - - :c:func:`Py_SIZE` - - :c:func:`Py_SET_SIZE` +- :c:func:`Py_SIZE` +- :c:func:`Py_SET_SIZE` Implications @@ -158,34 +237,23 @@ opaque means: - Variables of these types cannot be created. This mainly affects static ``PyModuleDef`` variables needed to define extension modules. - Extensions will need to switch to API added in :pep:`793`. + Virtually all extensions will need to switch the new export hook + added in :pep:`793` (:c:func:`PyModExport_modulename`) to support ``abi3t``. -The following functions will become unusable in practice (in the new Limited -API), since an extension cannot create valid, statically allocated, input -for them. To ease the transition for extension developers, -they will not yet be removed from the Limited API: +The following functions will become practically unusable in ``abi3t``, +since an extension cannot create valid, statically allocated, input +for them. +They will, however, not be removed. - :c:func:`PyModuleDef_Init` - :c:func:`PyModule_Create`, :c:func:`PyModule_Create2` - :c:func:`PyModule_FromDefAndSpec`, :c:func:`PyModule_FromDefAndSpec2` -New Export Hook (PEP 793) -------------------------- - -Implementation of this PEP requires :pep:`793` (``PyModExport``): -A new entry point for C extension modules), which was accepted for Python -3.15. - -Since existing ways of defining modules use API that this PEP removes -(namely, :c:type:`PyModuleDef`), extensions will need to migrate to PEP 793's -new “export hook” when switching to Limited API 3.15. - - Runtime ABI checks ------------------ -Users -- or rather the tools they use for building and installing extensions -- +Users -- or rather build/install tools acting on users' behalf -- will continue to be responsible for not putting incompatible extensions on Python's import paths. This decision makes sense since tools typically have much richer metadata than @@ -210,19 +278,19 @@ This slot will become *mandatory* with the new export hook added in (That PEP currently says “there are no required slots”; it will be updated.) -Check for older ``abi3`` -^^^^^^^^^^^^^^^^^^^^^^^^ +Check for non-free-threaded ABI in free-threading builds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Additionally, in free-threaded builds, :c:func:`PyModuleDef_Init` will detect -extensions using the pre-free-threading Stable ABI, emit an informative +extensions using the non-free-threading Stable ABI, emit an informative message when one is loaded, *and* raise an exception. (Implementation note: A message will be printed before raising the exception, because extensions that attempt to handle an exception using incompatible ABI will likely crash and lose the exception's message.) -This check for older ``abi3`` relies on internal bit patterns and may be -removed in future CPython versions, if the internal object layout needs -to change. +This check for non-free-threading ``abi3`` relies on internal bit patterns +and may be removed in future CPython versions, +if the internal object layout needs to change. The ``abi3t`` wheel tag @@ -230,44 +298,58 @@ The ``abi3t`` wheel tag Wheels that use a stable ABI compatible with free-threading CPython builds should use a new `ABI tag`_: ``abi3t``. -The name is chosen to reflect the fact that this ABI is similar to ``abi3``, -with limitations necessary to support free-threading (which uses the letter -``t`` in existing, version-specific ABI tags like ``cp314t``). .. _ABI tag: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#abi-tag +Recommendations for installers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Package installers should treat this tag as completely separate from ``abi3``. They should allow ``abi3t``-tagged wheels for free-threaded builds wherever -they currently allow ``abi3``-tagged ones for (orherwise equal) non-free-threaded -builds. +they currently allow ``abi3``-tagged ones for (orherwise equal) +non-free-threaded builds. -Build tools should generate ``abi3.abi3t`` instead of ``abi3`` when the Python -tag is ``cp315`` and above (or equivalently: when setting ``Py_LIMITED_API`` -to ``3.15`` (``0x030f0000``) or above). -``abi3.abi3t`` is a `compressed tag set`_ that signals compatibility with both -``abi3`` and ``abi3t``. +Recommendations for build tools +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _compressed tag set: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#compressed-tag-sets +Build tools should give users one or two additional options, in addition to +the existing CPython version-specific ABI (:samp:`cp3{nn}`) and +Stable ABI (``abi3``): -.. note:: +- Compile extensions compatible with *both* ``abi3`` and ``abi3t``, by either: - The version of the Stable ABI is indicated by the `Python wheel tag`_; this - PEP does not change that. - For example, a wheel tagged ``cp315-abi3.abi3t`` will be compatible with - 3.15, 3.16, and later versions; - ``cp317-abi3.abi3t`` will be compatible with 3.17+. + - defining both :samp:`Py_LIMITED_API={v}` and :samp:`Py_TARGET_ABI3T={v}`, or + - defining :samp:`Py_LIMITED_API={v}` and: + + - defining ``Py_GIL_DISABLED`` (on Windows) + - building with free-threaded CPython headers (elsewhere) + + Such extensions should be tagged with the `compressed tag set`_ + ``abi3.abi3t``. + +- Compile extensions compatible with *only* ``abi3t``, by defining only + :samp:`Py_TARGET_ABI3T={v}` and tagging the result with ``abi3t``. + This will initially offer no advantages over the ``abi3.abi3t`` option + above, but there is a possibility that it will become useful in the future. + +In the above, :samp:`{v}` stands for a the lowest Python version with which +the extension should be compatible, in :c:func:`Py_PACK_VERSION` format. +In the cases above, this version must be set to 3.15 or higher. + +.. _compressed tag set: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#compressed-tag-sets + +The version of the Stable ABI, both ``abi3`` and ``abi3t``, is indicated by +the `Python wheel tag`_. +For example, a wheel tagged ``cp315-abi3.abi3t`` will be compatible with +3.15, 3.16, and later versions; +``cp317-abi3.abi3t`` will be compatible with 3.17+. .. _Python wheel tag: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#python-tag -The ``abi3t`` tag can be used in extensions compatible with earlier versions of -free-threaded Python. -For example, an extension compatible with GIL-enabled *and* free-threaded -builds of *3.14*, 3.15, and higher versions would be tagged -``cpy314-abi3.abi3t``. -This PEP does not propose an official way to build such extensions, but since -a mechanism for that can be added later (see -:ref:`a Rejected idea `), installers should be ready to accept -the tag. +Note that this PEP does not provide a way to target Stable ABI for +Free-threaded Python 3.14 and below (``cp314-abi3t``). +This may change an the future, or with experimental build tools, so +*installers* should be prepared for such extensions. New API @@ -277,23 +359,26 @@ Implementing this PEP will make it possible to build extensions that can be successfully loaded on free-threaded Python, but not necessarily ones that are thread-safe without a GIL. -Limited API to allow thread-safety without a GIL -- presumably ``PyMutex``, ``PyCriticalSection``, and -similar -- will be added via the C API working group, or in a follow-up PEP. +Limited API to allow thread-safety without a GIL -- presumably ``PyMutex``, +``PyCriticalSection``, and similar -- will be added via the C API working group, +or in a follow-up PEP. Backwards and Forwards Compatibility ==================================== -Limited API 3.15 will not be backwards-compatible with older CPython releases, -due to the need to use new ``PyModExport`` API added in :pep:`793`. +Extensions targetting ``abi3t`` will not be backwards-compatible with older +CPython releases, due to the need to use new ``PyModExport`` API added +in :pep:`793`. -Extension authors who cannot switch may continue to use Limited API 3.14 -and below. +Extension authors who cannot switch may continue to use the existing ``abi3``, +that is, build on GIL-enabled Python without defining ``Py_GIL_DISABLED``. For compatibility with free-threaded builds, they can compile using -version-specific ABI -- for example, compile on CPython 3.15 without defining -``Py_LIMITED_API``. +version-specific ABI -- that is, compile ``abi3``-compatible source +on free-threaded CPython builds without defining ``Py_LIMITED_API``. -Limited API 3.15 will be forward-compatible with future versions of CPython 3.x. +Limited API 3.15 for free-threading is a subset of the existing Limited API, +and as such, it will be forward-compatible with future versions of CPython 3.x. Older versions of the Limited API (that is, 3.14 and below) will continue to be forward-compatible with GIL-enabled builds of CPython 3.x, starting with the version that introduced the given Limited API. @@ -373,7 +458,7 @@ free-threaded one. * ❌ * ✅ * ❌ - * * ``cp315-abi3t`` (*) + * * ``cp315-abi3t`` * ❌ * ❌ * ❌ @@ -393,71 +478,50 @@ free-threaded one. The following table summarizes which wheel tag should be used for an extension built with a given interpreter and ``Py_LIMITED_API`` macro: -.. list-table:: - :widths: auto - :header-rows: 1 - - * * To get the wheel tag… - * Compile on… - * with ``Py_LIMITED_API`` set to… - * Note - * * ``cp314-cp314`` - * 3.14 (GIL) - * (unset) - * existing - * * ``cp314-cp314t`` - * 3.14 (FT) - * (unset) - * existing - * * ``cp314-abi3`` - * 3.14+ (GIL) - * ``PY_PACK_VERSION(3, 14)`` - * existing - * * ``cp314-abi3t`` - * N/A - * N/A - * out of spec - * * ``cp314-abi3.abi3t`` - * N/A - * N/A - * reserved - * * ``cp315-cp315`` - * 3.15 (GIL) - * (unset) - * continued - * * ``cp315-cp315t`` - * 3.15 (FT) - * (unset) - * continued - * * ``cp315-abi3`` - * 3.15+ (GIL) - * ``PY_PACK_VERSION(3, 15)`` - * discontinued - * * ``cp315-abi3t`` - * N/A - * N/A - * out of spec - * * ``cp315-abi3.abi3t`` - * 3.15+ (any) - * ``PY_PACK_VERSION(3, 15)`` - * new ++-----------------------+-------------+--------------------+---------------------+-----------+ +| To get the wheel tag… | Compile on… | ``Py_LIMITED_API`` | ``Py_TARGET_ABI3T`` | Note | ++=======================+=============+====================+=====================+===========+ +| ``cp314-cp314`` | 3.14 (GIL) | --- | N/A | existing | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp314-cp314t`` | 3.14 (FT) | --- | N/A | existing | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp314-abi3`` | 3.14+ (GIL) | 3.14 | N/A | existing | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp314-abi3t`` | N/A | reserved | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp314-abi3.abi3t`` | N/A | reserved | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp315-cp315`` | 3.15 (GIL) | --- | --- | continued | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp315-cp315t`` | 3.15 (FT) | --- | --- | continued | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp315-abi3`` | 3.15+ (GIL) | 3.15 | --- | continued | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp315-abi3t`` | 3.15+ | --- | 3.15 | new | ++ +-------------+--------------------+---------------------+ + +| | 3.15+ (FT) | 3.15 | --- | | ++-----------------------+-------------+--------------------+---------------------+-----------+ +| ``cp315-abi3.abi3t`` | 3.15+ | 3.15 | 3.15 | new | ++-----------------------+-------------+--------------------+---------------------+-----------+ + + +In the “Compile on” column, *FT* means that the :c:macro:`Py_GIL_DISABLED` +macro must be defined -- either explicitly or, on non-Windows platforms, +by including CPython headers configured with :option:`--disable-gil`. +*GIL* means that :c:macro:`Py_GIL_DISABLED` must *not* be defined. + +In the ``Py_LIMITED_API`` and ``Py_TARGET_ABI3T``, a dash means the macro +must not be defined; a version means the macro must be set to the corresponding +integer in :c:func:`Py_PACK_VERSION` format. Values in the *Note* column: * *existing*: The wheel tag is currently in use * *continued*: The wheel tag continues the existing scheme -* *discontinued*: The wheel tag continues the existing scheme, but it will - be discouraged. Older tools may still generate it. Installers will - continue to accept it, but only for GIL-enabled builds, even though the wheel - would be compatible with free-threaded ones. * *new*: Proposed in this PEP. * *reserved*: A mechanism to build a matching extension is not proposed in this PEP, but may be added in the future. Installers should be prepared to handle the tag. -* *out of spec*: Should not be used as-is: extensions should be tagged - ``abi3.abi3t`` rather than only ``abi3``. - The entry is included for installers that decompose compressed tag sets. - Security Implications ===================== @@ -496,23 +560,21 @@ Rejected Ideas ============== -Add an alternative stable ABI for free-threading ------------------------------------------------- +Make ``PyObject`` opaque in Limited API 3.15 +-------------------------------------------- -It would be possible to: +It would be possible to make ``PyObject`` struct opaque in Limited API 3.15 +(that is, the new version of the existing Limited API), +rather than introduce a new variant of the Stable ABI and Limited API. -- Add a new stable ABI (“``abi3t``”) specifically for free-threading, - which would be incompatible with the existing ``abi3``. - Extensions would need no code changes to target ``abi3t`` and builds would be - compatible with free-threaded CPython (3.14 and above). -- Define an additional macro (“``Py_OPAQUE_PYOBJECT``”), which would make - ``PyObject`` opaque as in this PEP. Extensions would need code changes as in - this PEP, and as in this PEP, compiled extensions (“``abi3.abi3t``”) would - be compatible with all builds of CPython 3.15+. +This would mean that extension authors would need to adapt their code to the +new limitations, or abandon Limited API altogether, in order to use any C API +introduced in Python 3.15. -This scheme was rejected as too complex. -It would also make the free-threading memory layout of ``PyObject`` part -of the stable ABI, preventing future adjustments. +It would also not remove the need for a new wheel tag (``abi3t``), +which would be required to express that an extension +is compatible with both GIL-enabled and free-threaded builds +of CPython 3.14 or lower. .. _pep803-no-shim: @@ -547,29 +609,11 @@ extension to query the running interpreter, and for 3.14, use a ``struct`` definition corresponding to the detected build's ``PyModuleDef``. -.. _pep803-no-avoid-abi3t: - -Using the Python version wheel tag to determine compatibility -------------------------------------------------------------- - -A previous version of this PEP avoided adding a new wheel tag (``abi3t``), -and specified that wheels tagged ``abi3`` would be compatible with -free-threading if the *Python tag* is ``cp315`` or higher. - -Such a scheme would work for this PEP, but it cannot express that an extension -is compatible with both GIL-enabled and free-threaded builds -of CPython 3.14 or lower. -Adding a new explicit tag means that *if* we allow building such wheels in the -future, packaging tools should not need additional changes to support them. -They would be tagged ``cp314-abi3.abi3t``. - - -Adding an ``abi4`` wheel tag ----------------------------- +Naming this ``abi4`` +-------------------- -Instead of ``abi3t``, we could “bump the version” and use ``abi4`` instead -as the wheel ABI tag. -In the wheel tag, the difference is largely cosmetic. +Instead of ``abi3t``, we could “bump the version” and use ``abi4`` instead. +The difference is largely cosmetic. However, one thing this PEP does not propose is changing the *filename* tag: extensions will be named with the extensions like ``.abi3.so``. @@ -579,7 +623,7 @@ an unnecessary technical change. Using ``abi3.abi4`` in wheel tags but only ``.abi3`` in filenames would look more inconsistent than ``abi3.abi3t`` and ``.abi3``. -If we add ``abi4`` tag, the ``Py_LIMITED_API`` value would either need to: +If we added an ``abi4`` tag, the ``Py_LIMITED_API`` value would either need to: * change to start with ``4`` to match ``abi4``, but no longer correspond to ``PY_VERSION_HEX`` (making it harder to generate and check), or @@ -590,6 +634,29 @@ better as a transitional state before larger changes like :pep:`809`'s ``abi2026``. +Reusing ``Py_GIL_DISABLED`` to enable the new ABI +------------------------------------------------- + +It would be possible to select ``abi3t`` (rather than ``abi3``) when the +``Py_GIL_DISABLED`` macro is defined together with ``Py_LIMITED_API``. + +This would require annoying fiddling with buil flags, and make it +especially cumbersome to target *both* ``abi3`` and ``abi3t`` at the same time. + + +Making the new version of ``abi3`` compatible with free-threading +----------------------------------------------------------------- + +It would be possible to make ``PyObject`` opaque in Limited API 3.15, +rather than add a new stable ABI. +This would make all extensions built for the Stable ABI 3.15 and above +compatible with both free-threading and GIL-enabled Python. + +In the `PEP discussion `__, +the ability to build for the GIL-only Stable ABI with no source changes +was deemed to be worth an extra configuration macro (``Py_TARGET_ABI3T``). + + Copyright =========