@@ -7,6 +7,7 @@ Type: Standards Track
77Requires: 703, 793, 697
88Created: 19-Aug-2025
99Python-Version: 3.15
10+ Post-History: `08-Sep-2025 <https://discuss.python.org/t/103628 >`__
1011
1112
1213Abstract
@@ -18,6 +19,9 @@ To allow this, the :c:type:`PyObject` internal structure and related APIs
1819will be removed from version 3.15 of the Limited API, requiring migration to
1920new API for common tasks like defining modules and most classes.
2021
22+ Binary distributions (wheels) built with Limited API version 3.15 and above
23+ should use the ABI tag ``abi3.abi3t ``.
24+
2125
2226Terminology
2327===========
@@ -77,11 +81,14 @@ One ABI
7781 A single compiled extension module should support both
7882 free-threaded and GIL-enabled builds.
7983
80- No backwards compatibility
84+ No backwards compatibility now
8185 The new limited API will not support CPython 3.14 and below.
8286 Projects that need this support can build separate extensions specifically
8387 for the 3.14 free-threaded interpreter, and for older stable ABI versions.
8488
89+ However, we won't block the possibility of extending compatibility to
90+ CPython 3.14 and below.
91+
8592API changes are OK
8693 The new Limited API may require extension authors to make significant
8794 changes to their code.
@@ -116,12 +123,12 @@ Version 3.15 of the Limited API will:
116123 - :c:macro: `!_PyObject_EXTRA_INIT `
117124 - :c:macro: `PyObject_HEAD_INIT `
118125 - :c:macro: `PyObject_VAR_HEAD `
126+ - :c:func: `Py_SET_TYPE `
119127
120- - no longer include these function-like macros:
128+ - export the following as functions in the ABI, rather than macros:
121129
122130 - :c:func: `Py_SIZE `
123131 - :c:func: `Py_SET_SIZE `
124- - :c:func: `Py_SET_TYPE `
125132
126133
127134Implications
@@ -164,7 +171,7 @@ they will not yet be removed from the Limited API:
164171New Export Hook (PEP 793)
165172-------------------------
166173
167- Implementation of this PEP requires :pep: `793 ` (``PyModExport ``:
174+ Implementation of this PEP requires :pep: `793 ` (``PyModExport ``) :
168175A new entry point for C extension modules) to be
169176accepted, providing a new “export hook” for defining extension modules.
170177Using the new hook will become mandatory in Limited API 3.15.
@@ -207,17 +214,19 @@ removed in future CPython versions, if the internal object layout needs
207214to change.
208215
209216
210- Wheel tags
211- ----------
217+ The `` abi3t `` wheel tag
218+ -----------------------
212219
213- PyPA build tools should not need changes: if they allow the user to set the
214- limited API version, setting it to 3.15 should define :c:macro: `Py_LIMITED_API `
215- to ``0x030f0000 ``.
216- The resulting wheel should be tagged with the Python-ABI tag ``cp315-abi3 ``.
220+ Wheels that use a stable ABI compatible with free-threading CPython builds
221+ should use a new ABI tag: ``abi3t ``.
222+ The 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 ``).
217225
218- Installers and other tools should assume that wheels with a *python tag *
219- ``cp315 `` and above and ABI tag ``abi3 `` are compatible with free-threaded
220- builds.
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 ``.
221230
222231
223232New API
@@ -231,18 +240,140 @@ Limited API to allow thread-safety without a GIL -- presumably ``PyMutex``, ``Py
231240similar -- will be added via the C API working group, or in a follow-up PEP.
232241
233242
234- Backwards Compatibility
235- =======================
243+ Backwards and Forwards Compatibility
244+ ====================================
236245
237246Limited API 3.15 will not be backwards-compatible with older CPython releases,
238- due to removed structs and functions .
247+ due to the need to use new `` PyModExport `` API added in :pep: ` 793 ` .
239248
240249Extension authors who cannot switch may continue to use Limited API 3.14
241250and below.
242251For compatibility with free-threaded builds, they can compile using
243252version-specific ABI -- for example, compile on CPython 3.15 without defining
244253``Py_LIMITED_API ``.
245254
255+ Limited API 3.15 will be forward-compatible with future versions of CPython 3.x.
256+ Older versions of the Limited API (that is, 3.14 and below) will continue
257+ to be forward-compatible with GIL-enabled builds of CPython 3.x, starting with
258+ the version that introduced the given Limited API.
259+
260+
261+ Compatibility Overview
262+ ----------------------
263+
264+ The following table summarizes compatibility of wheel tags with CPython
265+ interpreters. “GIL” stands for GIL-enabled interpreter; “FT” stands for a
266+ free-threaded one.
267+
268+ .. list-table ::
269+ :widths: auto
270+ :header-rows: 1
271+
272+ * * Wheel tag
273+ * 3.14 (GIL)
274+ * 3.14 (FT)
275+ * 3.15 (GIL)
276+ * 3.15 (FT)
277+ * 3.16+ (GIL)
278+ * 3.16+ (FT)
279+ * * ``cp314-cp314 ``
280+ * ✅
281+ * ❌
282+ * ❌
283+ * ❌
284+ * ❌
285+ * ❌
286+ * * ``cp314-cp314t ``
287+ * ❌
288+ * ✅
289+ * ❌
290+ * ❌
291+ * ❌
292+ * ❌
293+ * * ``cp314-abi3 ``
294+ * ✅
295+ * ❌
296+ * ✅
297+ * ❌
298+ * ✅
299+ * ❌
300+ * * ``cp315-cp315 ``
301+ * ❌
302+ * ❌
303+ * ✅
304+ * ❌
305+ * ❌
306+ * ❌
307+ * * ``cp315-cp315t ``
308+ * ❌
309+ * ❌
310+ * ❌
311+ * ✅
312+ * ❌
313+ * ❌
314+ * * ``cp315-abi3 ``
315+ * ❌
316+ * ❌
317+ * ✅
318+ * ❌
319+ * ✅
320+ * ❌
321+ * * ``cp315-abi3.abi3t ``
322+ * ❌
323+ * ❌
324+ * ✅
325+ * ✅
326+ * ✅
327+ * ✅
328+
329+ The following table summarizes which wheel tag should be used for an extension
330+ built with a given interpreter and ``Py_LIMITED_API `` macro:
331+
332+ .. list-table ::
333+ :widths: auto
334+ :header-rows: 1
335+
336+ * * To get the wheel tag…
337+ * Compile on…
338+ * with ``Py_LIMITED_API `` set to…
339+ * Note
340+ * * ``cp314-cp314 ``
341+ * 3.14 (GIL)
342+ * (unset)
343+ * existing
344+ * * ``cp314-cp314t ``
345+ * 3.14 (FT)
346+ * (unset)
347+ * existing
348+ * * ``cp314-abi3 ``
349+ * 3.14+ (GIL)
350+ * ``PY_PACK_VERSION(3, 14) ``
351+ * existing
352+ * * ``cp315-cp315 ``
353+ * 3.15 (GIL)
354+ * (unset)
355+ * continued
356+ * * ``cp315-cp315t ``
357+ * 3.15 (FT)
358+ * (unset)
359+ * continued
360+ * * ``cp315-abi3 ``
361+ * 3.15+ (GIL)
362+ * ``PY_PACK_VERSION(3, 15) ``
363+ * discontinued
364+ * * ``cp315-abi3.abi3t ``
365+ * 3.15+ (any)
366+ * ``PY_PACK_VERSION(3, 15) ``
367+ * new
368+
369+ Values in the *Note * column:
370+
371+ * *existing *: The wheel tag is currently in use
372+ * *continued *: The wheel tag continues the existing scheme
373+ * *discontinued *: The wheel tag continues the existing scheme, but it will
374+ be discouraged. Older tools may still generate it.
375+ * *new *: Proposed in this PEP.
376+
246377
247378Security Implications
248379=====================
@@ -268,10 +399,10 @@ This PEP combines several pieces, implemented individually:
268399 Implemented in GitHub pull request `python/cpython#136505
269400 <https://github.com/python/cpython/pull/136505> `__.
270401- For ``PyModExport ``, see :pep: `793 `.
271- - For a version-checking slot, see GitHub pull request ` python/cpython#137212
272- <https://github.com/python/cpython/pull/137212> `__.
273- - For a check for older ``abi3 ``, see GitHub pull request ` python/cpython#137957
274- <https://github.com/python/cpython/pull/137957> `__.
402+ - A version-checking slot was implemented in GitHub pull request
403+ ` python/cpython#137212 <https://github.com/python/cpython/pull/137212 >`__.
404+ - A check for older ``abi3 `` was implemented in GitHub pull request
405+ ` python/cpython#137957 <https://github.com/python/cpython/pull/137957 >`__.
275406- For wheel tags, there is no implementation yet.
276407- A porting guide is not yet written.
277408
@@ -285,26 +416,24 @@ Add an alternative stable ABI for free-threading
285416
286417It would be possible to:
287418
288- - Keep the current stable ABI (“``abi3 ``”) unchanged (except additions, as done
289- in each release). Extensions would need no code changes and builds would be
290- compatible with old and new GIL-enabled CPython versions.
291- - Add a new stable ABI (“``abi3t ``”) specifically for free-threading.
292- Extensions would need no code changes and builds would be
419+ - Add a new stable ABI (“``abi3t ``”) specifically for free-threading,
420+ which would be incompatible with the existing ``abi3 ``.
421+ Extensions would need no code changes to target ``abi3t `` and builds would be
293422 compatible with free-threaded CPython (3.14 and above).
294- - Defining an additional macro (“``Py_OPAQUE_PYOBJECT ``”) would make
423+ - Define an additional macro (“``Py_OPAQUE_PYOBJECT ``”), which would make
295424 ``PyObject `` opaque as in this PEP. Extensions would need code changes as in
296- this PEP, and compiled extensions (“``abi3.abi3t ``”) would be compatible with
297- all builds of CPython 3.15+.
425+ this PEP, and as in this PEP, compiled extensions (“``abi3.abi3t ``”) would
426+ be compatible with all builds of CPython 3.15+.
298427
299428This scheme was rejected as too complex.
300429It would also make the free-threading memory layout of ``PyObject `` part
301430of the stable ABI, preventing future adjustments.
302431
303432
304- Shim for compatibility with CPython 3.14
305- ----------------------------------------
433+ Shims for compatibility with CPython 3.14
434+ -----------------------------------------
306435
307- The issue that prevents compatibility with Python 3.14 is that with
436+ The main issue that prevents compatibility with Python 3.14 is that with
308437opaque ``PyObject `` and ``PyModuleDef ``, it is not feasible to initialize
309438an extension module.
310439The solution, :pep: `793 `, is only being added in Python 3.15.
@@ -314,16 +443,39 @@ free-threading and GIL-enabled) are “frozen”, so it is possible for an
314443extension to query the running interpreter, and for 3.14, use
315444a ``struct `` definition corresponding to the detected build's ``PyModuleDef ``.
316445
317- This is too onerous to support and test in CPython's Limited API.
318- It would also require adding a new wheel tag (e.g. ``abi3t ``) that all install
319- tools would need to recognize. (This PEP's ``cp315-abi3 `` is incompatible
320- with Python 3.14.)
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.
321448
322449
323- Open Issues
324- ===========
450+ Using the Python wheel tag to determine compatibility
451+ -----------------------------------------------------
452+
453+ A previous version of this PEP avoided adding a new wheel tag (``abi3t ``),
454+ and specified that wheels tagged ``abi3 `` would be compatible with
455+ free-threading if the *Python tag * is ``cp315 `` or higher.
456+
457+ Such a scheme would work for this PEP, but it cannot express that an extension
458+ is compatible with both GIL-enabled and free-threaded builds
459+ of CPython 3.14 or lower.
460+ Adding a new explicit tag means that *if * we allow building such wheels in the
461+ future, packaging tools should not need additional changes to support them.
462+ They would be tagged ``cp314-abi3.abi3t ``.
463+
464+
465+ Adding an ``abi4 `` wheel tag
466+ ----------------------------
467+
468+ Instead of ``abi3t ``, we could “bump the version” and use ``abi4 `` instead
469+ as the wheel ABI tag.
470+ In the wheel tag, the difference is largely cosmetic.
471+
472+ However, one thing this PEP does not propose is changing the *filename *
473+ tag: extensions will be named with the extensions like ``.abi3.so ``.
474+ Changing this while keeping compatibility with GIL-enabled builds would be
475+ an unnecessary technical change.
325476
326- [See discussion for now.]
477+ Using ``abi3.abi4 `` in wheel tags but only ``.abi3 `` in filenames would
478+ look more inconsistent than ``abi3.abi3t `` and ``.abi3 ``.
327479
328480
329481Copyright
0 commit comments