@@ -63,12 +63,13 @@ to those builds.
6363To build against the Stable ABI, the extension must use a *Limited API *,
6464that is, only a subset of the functions, structures, etc. that CPython
6565exposes.
66- The Limited API is versioned, and building against Limited API 3.X
67- yields an extension that is ABI-compatible with CPython 3.X and *any * later
68- version (though bugs in CPython sometimes cause incompatibilities in practice).
69- Also, the Limited API is not “stable”: newer versions may remove API that
70- were a part of older versions.
66+ Both the Limited API and the Stable ABI are versioned, and building against
67+ Stable ABI 3.X requires using only Limited API 3.X, and yields an extension
68+ that is ABI-compatible with CPython 3.X and *any * later version
69+ (though bugs in CPython sometimes cause incompatibilities in practice).
7170
71+ The Limited API is not “stable”: newer versions may remove API that
72+ were a part of older versions.
7273This PEP proposes the most significant such removal to date.
7374
7475
@@ -88,6 +89,7 @@ No backwards compatibility now
8889
8990 However, we won't block the possibility of extending compatibility to
9091 CPython 3.14 and below.
92+ See a :ref: `rejected idea <pep803-no-shim >` for how this could work.
9193
9294API changes are OK
9395 The new Limited API may require extension authors to make significant
@@ -172,9 +174,12 @@ New Export Hook (PEP 793)
172174-------------------------
173175
174176Implementation of this PEP requires :pep: `793 ` (``PyModExport ``):
175- A new entry point for C extension modules) to be
176- accepted, providing a new “export hook” for defining extension modules.
177- Using the new hook will become mandatory in Limited API 3.15.
177+ A new entry point for C extension modules), which was accepted for Python
178+ 3.15.
179+
180+ Since existing ways of defining modules use API that this PEP removes
181+ (namely, :c:type: `PyModuleDef `), extensions will need to migrate to PEP 793's
182+ new “export hook” when switching to Limited API 3.15.
178183
179184
180185Runtime ABI checks
@@ -185,6 +190,12 @@ will continue to be responsible for not putting incompatible extensions on
185190Python's import paths.
186191This decision makes sense since tools typically have much richer metadata than
187192what CPython can check.
193+ Typically, build tools and installers use `PyPA packaging metadata `_ and
194+ `platform compatibility tags `_ to communicate compatibility details, but other
195+ models are possible.
196+
197+ .. _PyPA packaging metadata : https://packaging.python.org/en/latest/specifications/core-metadata/
198+ .. _platform compatibility tags : https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/
188199
189200However, CPython will add a line of defense against outdated or misconfigured
190201tools, or human mistakes, in the form of a new *module slot * containing
@@ -218,15 +229,45 @@ The ``abi3t`` wheel tag
218229-----------------------
219230
220231Wheels that use a stable ABI compatible with free-threading CPython builds
221- should use a new ABI tag: ``abi3t ``.
232+ should use a new ` ABI tag `_ : ``abi3t ``.
222233The name is chosen to reflect the fact that this ABI is similar to ``abi3 ``,
223- except changes necessary to support free-threading (which uses the letter ``t ``
224- in existing, version-specific ABI tags like ``cp314t ``).
234+ with limitations necessary to support free-threading (which uses the letter
235+ ``t `` in existing, version-specific ABI tags like ``cp314t ``).
236+
237+ .. _ABI tag : https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#abi-tag
238+
239+ Package installers should treat this tag as completely separate from ``abi3 ``.
240+ They should allow ``abi3t ``-tagged wheels for free-threaded builds wherever
241+ they currently allow ``abi3 ``-tagged ones for (orherwise equal) non-free-threaded
242+ builds.
243+
244+ Build tools should generate ``abi3.abi3t `` instead of ``abi3 `` when the Python
245+ tag is ``cp315 `` and above (or equivalently: when setting ``Py_LIMITED_API ``
246+ to ``3.15 `` (``0x030f0000 ``) or above).
247+ ``abi3.abi3t `` is a `compressed tag set `_ that signals compatibility with both
248+ ``abi3 `` and ``abi3t ``.
249+
250+ .. _compressed tag set : https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#compressed-tag-sets
251+
252+ .. note ::
253+
254+ The version of the Stable ABI is indicated by the `Python wheel tag `_; this
255+ PEP does not change that.
256+ For example, a wheel tagged ``cp315-abi3.abi3t `` will be compatible with
257+ 3.15, 3.16, and later versions;
258+ ``cp317-abi3.abi3t `` will be compatible with 3.17+.
225259
226- Since wheels built using Limited API 3.15 will be compatible with both
227- GIL-enabled builds and free-threaded ones, they should use the
228- `compressed ABI tag set <https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#compressed-tag-sets >`__
229- ``abi3.abi3t ``.
260+ .. _Python wheel tag : https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/#python-tag
261+
262+ The ``abi3t `` tag can be used in extensions compatible with earlier versions of
263+ free-threaded Python.
264+ For example, an extension compatible with GIL-enabled *and * free-threaded
265+ builds of *3.14 *, 3.15, and higher versions would be tagged
266+ ``cpy314-abi3.abi3t ``.
267+ This PEP does not propose an official way to build such extensions, but since
268+ a mechanism for that can be added later (see
269+ :ref: `a Rejected idea <pep803-no-shim >`), installers should be ready to accept
270+ the tag.
230271
231272
232273New API
@@ -297,6 +338,20 @@ free-threaded one.
297338 * ❌
298339 * ✅
299340 * ❌
341+ * * ``cp314-abi3t `` (*)
342+ * ❌
343+ * ✅
344+ * ❌
345+ * ✅
346+ * ❌
347+ * ✅
348+ * * ``cp314-abi3.abi3t `` (*)
349+ * ✅
350+ * ✅
351+ * ✅
352+ * ✅
353+ * ✅
354+ * ✅
300355 * * ``cp315-cp315 ``
301356 * ❌
302357 * ❌
@@ -318,6 +373,13 @@ free-threaded one.
318373 * ❌
319374 * ✅
320375 * ❌
376+ * * ``cp315-abi3t `` (*)
377+ * ❌
378+ * ❌
379+ * ❌
380+ * ✅
381+ * ❌
382+ * ✅
321383 * * ``cp315-abi3.abi3t ``
322384 * ❌
323385 * ❌
@@ -326,6 +388,8 @@ free-threaded one.
326388 * ✅
327389 * ✅
328390
391+ (*): Wheels with these tags cannot be built; see table below
392+
329393The following table summarizes which wheel tag should be used for an extension
330394built with a given interpreter and ``Py_LIMITED_API `` macro:
331395
@@ -349,6 +413,14 @@ built with a given interpreter and ``Py_LIMITED_API`` macro:
349413 * 3.14+ (GIL)
350414 * ``PY_PACK_VERSION(3, 14) ``
351415 * existing
416+ * * ``cp314-abi3t ``
417+ * N/A
418+ * N/A
419+ * out of spec
420+ * * ``cp314-abi3.abi3t ``
421+ * N/A
422+ * N/A
423+ * reserved
352424 * * ``cp315-cp315 ``
353425 * 3.15 (GIL)
354426 * (unset)
@@ -361,6 +433,10 @@ built with a given interpreter and ``Py_LIMITED_API`` macro:
361433 * 3.15+ (GIL)
362434 * ``PY_PACK_VERSION(3, 15) ``
363435 * discontinued
436+ * * ``cp315-abi3t ``
437+ * N/A
438+ * N/A
439+ * out of spec
364440 * * ``cp315-abi3.abi3t ``
365441 * 3.15+ (any)
366442 * ``PY_PACK_VERSION(3, 15) ``
@@ -371,8 +447,16 @@ Values in the *Note* column:
371447* *existing *: The wheel tag is currently in use
372448* *continued *: The wheel tag continues the existing scheme
373449* *discontinued *: The wheel tag continues the existing scheme, but it will
374- be discouraged. Older tools may still generate it.
450+ be discouraged. Older tools may still generate it. Installers will
451+ continue to accept it, but only for GIL-enabled builds, even though the wheel
452+ would be compatible with free-threaded ones.
375453* *new *: Proposed in this PEP.
454+ * *reserved *: A mechanism to build a matching extension is not proposed in
455+ this PEP, but may be added in the future.
456+ Installers should be prepared to handle the tag.
457+ * *out of spec *: Should not be used as-is: extensions should be tagged
458+ ``abi3.abi3t `` rather than only ``abi3 ``.
459+ The entry is included for installers that decompose compressed tag sets.
376460
377461
378462Security Implications
@@ -398,7 +482,8 @@ This PEP combines several pieces, implemented individually:
398482 ``_Py_OPAQUE_PYOBJECT `` macro.
399483 Implemented in GitHub pull request `python/cpython#136505
400484 <https://github.com/python/cpython/pull/136505> `__.
401- - For ``PyModExport ``, see :pep: `793 `.
485+ - For ``PyModExport ``, see :pep: `793 ` and
486+ `GitHub issue #140550 <https://github.com/python/cpython/issues/140550 >`_.
402487- A version-checking slot was implemented in GitHub pull request
403488 `python/cpython#137212 <https://github.com/python/cpython/pull/137212 >`__.
404489- A check for older ``abi3 `` was implemented in GitHub pull request
@@ -430,9 +515,27 @@ It would also make the free-threading memory layout of ``PyObject`` part
430515of the stable ABI, preventing future adjustments.
431516
432517
518+ .. _pep803-no-shim :
519+
433520Shims for compatibility with CPython 3.14
434521-----------------------------------------
435522
523+ It’s possible to build a ``cp314-abi3.abi3t `` extension – one compatible
524+ with 3.14 (both free-threaded build and default).
525+ There are several challenges around this:
526+
527+ * making it convenient and safe for general extensions
528+ * testing it (as CPython’s test suite doesn’t involve other CPython versions
529+ than the one being tested)
530+
531+ So, providing a mechanism to build such extensions is best suited to an
532+ external project (for example, one like `pythoncapi-compat `_).
533+ It's out of scope for CPython’s C API, and this PEP.
534+
535+ .. _pythoncapi-compat : https://github.com/python/pythoncapi-compat
536+
537+ To sketch how such a mechanism could work:
538+
436539The main issue that prevents compatibility with Python 3.14 is that with
437540opaque ``PyObject `` and ``PyModuleDef ``, it is not feasible to initialize
438541an extension module.
@@ -443,12 +546,11 @@ free-threading and GIL-enabled) are “frozen”, so it is possible for an
443546extension to query the running interpreter, and for 3.14, use
444547a ``struct `` definition corresponding to the detected build's ``PyModuleDef ``.
445548
446- This is too onerous to support and test in CPython's Limited API at this point,
447- but it may be allowed in the future.
448549
550+ .. _pep803-no-avoid-abi3t :
449551
450- Using the Python wheel tag to determine compatibility
451- -----------------------------------------------------
552+ Using the Python version wheel tag to determine compatibility
553+ -------------------------------------------------------------
452554
453555A previous version of this PEP avoided adding a new wheel tag (``abi3t ``),
454556and specified that wheels tagged ``abi3 `` would be compatible with
@@ -477,6 +579,16 @@ an unnecessary technical change.
477579Using ``abi3.abi4 `` in wheel tags but only ``.abi3 `` in filenames would
478580look more inconsistent than ``abi3.abi3t `` and ``.abi3 ``.
479581
582+ If we add ``abi4 `` tag, the ``Py_LIMITED_API `` value would either need to:
583+
584+ * change to start with ``4 `` to match ``abi4 ``, but no longer correspond
585+ to ``PY_VERSION_HEX `` (making it harder to generate and check), or
586+ * not change, making it inconsistent with ``abi4 ``.
587+
588+ Adding ``abi3t `` is a smaller change than adding ``abi4 ``, making it work
589+ better as a transitional state before larger changes like :pep: `809 `'s
590+ ``abi2026 ``.
591+
480592
481593Copyright
482594=========
0 commit comments