Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 16 additions & 31 deletions peps/pep-0743.rst
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
PEP: 743
Title: Add Py_COMPAT_API_VERSION to the Python C API
Title: Add Py_OMIT_LEGACY_API to the Python C API
Author: Victor Stinner <vstinner@python.org>,
Petr Viktorin <encukou@gmail.com>,
PEP-Delegate: C API Working Group
Discussions-To: https://discuss.python.org/t/pep-743-add-py-compat-api-version-to-the-python-c-api-take-2/59323
Status: Draft
Type: Standards Track
Created: 11-Mar-2024
Python-Version: 3.14
Python-Version: 3.15

.. highlight:: c


Abstract
========

Add ``Py_COMPAT_API_VERSION`` C macro that hides some deprecated and
Add ``Py_OMIT_LEGACY_API`` C macro that hides deprecated and
soft-deprecated symbols, allowing users to opt out of using API with known
issues that other API solves.
The macro is versioned, allowing users to update (or not) on their own pace.

Also, add namespaced alternatives for API without the ``Py_`` prefix,
and soft-deprecate the original names.
Expand Down Expand Up @@ -81,7 +80,7 @@ It might be be sufficient to leave this to third-party linters.
For that we'd need a good way to expose a list of (soft-)deprecated
API to such linters.
While adding that, we can -- rather easily -- do the linter's job directly
in CPython headers, avoiding the neel for an extra tool.
in CPython headers, avoiding the need for an extra tool.
Unlike Python, C makes it rather easy to limit available API -- for a whole
project or for each individual source file -- by having users define
an “opt-in” macro.
Expand All @@ -91,11 +90,6 @@ available API to a subset that compiles to stable ABI. (In hindsight, we should
have used a different macro name for that particular kind of limiting, but it's
too late to change that now.)

To prevent working code from breaking as we identify more “undesirable” API
and add safer alternatives to it, the opt-in macro should be *versioned*.
Users can choose a version they need based on their compatibility requirements,
and update it at their own pace.

To be clear, this mechanism is *not* a replacement for deprecation.
Deprecation is for API that prevents new features or optimizations, or
presents a security risk or maintenance burden.
Expand Down Expand Up @@ -126,7 +120,7 @@ third-party libraries.
Specification
=============

We introduce a ``Py_COMPAT_API_VERSION`` macro.
We introduce a ``Py_OMIT_LEGACY_API`` macro.
If this macro is defined before ``#include <Python.h>``, some API definitions
-- as described below -- will be omitted from the Python header files.

Expand All @@ -142,17 +136,11 @@ of CPython, and is finalized in each 3.x.0 Beta 1 release.
In rare cases, entries can be removed (i.e. made available for use) at any
time.

The macro should be defined to a version in the format used by
``PY_VERSION_HEX``, with the “micro”, “release” and “serial” fields
set to zero.
For example, to omit API deemed undesirable in 3.14.0b1, users should define
``Py_COMPAT_API_VERSION`` to ``0x030e0000``.


Requirements for omitted API
----------------------------

An API that is omitted with ``Py_COMPAT_API_VERSION`` must:
An API that is omitted with ``Py_OMIT_LEGACY_API`` must:

- be soft-deprecated (see :pep:`387`);
- for all known use cases of the API, have a documented alternative
Expand All @@ -164,15 +152,15 @@ An API that is omitted with ``Py_COMPAT_API_VERSION`` must:
- be approved by the C API working group. (The WG may give blanket approvals
for groups of related API; see *Initial set* below for examples.)

Note that ``Py_COMPAT_API_VERSION`` is meant for API that can be trivially
Note that ``Py_OMIT_LEGACY_API`` is meant for API that can be trivially
replaced by a better alternative.
API without a replacement should generally be deprecated instead.


Location
--------

All API definitions omitted by ``Py_COMPAT_API_VERSION`` will be moved to
All API definitions omitted by ``Py_OMIT_LEGACY_API`` will be moved to
a new header, ``Include/legacy.h``.

This is meant to help linter authors compile lists, so they can flag the API
Expand Down Expand Up @@ -200,8 +188,7 @@ Exceptions are possible if there is a good reason for them.
Initial set
-----------

The following API will be omitted with ``Py_COMPAT_API_VERSION`` set to
``0x030e0000`` (3.14) or greater:
The following API will be omitted with ``Py_OMIT_LEGACY_API`` set:

- Omit API returning borrowed references:

Expand Down Expand Up @@ -289,7 +276,7 @@ The following API will be omitted with ``Py_COMPAT_API_VERSION`` set to

The header file ``structmember.h``, which is not included from ``<Python.h>``
and must be included separately, will ``#error`` if
``Py_COMPAT_API_VERSION`` is defined.
``Py_OMIT_LEGACY_API`` is defined.
This affects the following API:

==================================== ==============================
Expand Down Expand Up @@ -346,7 +333,7 @@ The following API will be omitted with ``Py_COMPAT_API_VERSION`` set to

If any of these proposed replacements, or associated documentation,
are not added in time for 3.14.0b1, they'll be omitted with later versions
of ``Py_COMPAT_API_VERSION``.
of ``Py_OMIT_LEGACY_API``.
(We expect this for macros generated by ``configure``: ``HAVE_*``, ``WITH_*``,
``ALIGNOF_*``, ``SIZEOF_*``, and several without a common prefix.)

Expand All @@ -357,20 +344,18 @@ Implementation
TBD


Open issues
===========

The name ``Py_COMPAT_API_VERSION`` was taken from the earlier PEP;
it doesn't fit this version.


Backwards Compatibility
=======================

The macro is backwards compatible.
Developers can introduce and update the macro on their own pace, potentially
for one source file at a time.

Future versions of CPython may add more API to the set that
``Py_OMIT_LEGACY_API`` hides, breaking user code.
The fix is to undefine the macro (which is safe to do) or rework the
code.


Discussions
===========
Expand Down