Skip to content

Commit 0c57537

Browse files
encukouCAM-Gerlachezio-melotti
authored
PEP 689: Add docs for unstable C API (#1060)
Add docs for unstable C API (PEP 689) Co-authored-by: C.A.M. Gerlach <[email protected]> Co-authored-by: Ezio Melotti <[email protected]>
1 parent 4d5e7d4 commit 0c57537

File tree

1 file changed

+121
-12
lines changed

1 file changed

+121
-12
lines changed

developer-workflow/c-api.rst

+121-12
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44
Changing Python's C API
55
=======================
66

7-
The C API is divided into three sections:
7+
The C API is divided into these tiers:
88

99
1. The internal, private API, available with ``Py_BUILD_CORE`` defined.
1010
Ideally declared in ``Include/internal/``. Any API named with a leading
1111
underscore is also considered private.
12-
2. The public C API, available when ``Python.h`` is included normally.
12+
2. The Unstable C API, identified by the ``PyUnstable_`` name prefix.
13+
Ideally declared in :cpy-file:`Include/cpython/` along with the general public API.
14+
3. The “general” public C API, available when :cpy-file:`Include/Python.h` is included normally.
1315
Ideally declared in ``Include/cpython/``.
14-
3. The Limited API, available with ``Py_LIMITED_API`` defined.
16+
4. The Limited C API, available with :c:macro:`Py_LIMITED_API` defined.
1517
Ideally declared directly under ``Include/``.
1618

17-
Each section has higher stability & maintenance requirements, and you will
18-
need to think about more issues when you add or change definitions in it.
19+
Each tier has different stability and maintenance requirements to consider
20+
when you add or change definitions in it.
1921

2022
The compatibility guarantees for public C API are explained in the
2123
user documentation, ``Doc/c-api/stable.rst`` (:ref:`python:stable`).
@@ -29,13 +31,19 @@ for building CPython itself, as indicated by a macro like ``Py_BUILD_CORE``.
2931

3032
While internal API can be changed at any time, it's still good to keep it
3133
stable: other API or other CPython developers may depend on it.
34+
For users, internal API is sometimes the best workaround for a thorny problem
35+
--- though those use cases should be discussed on the
36+
`C API Discourse category <https://discuss.python.org/c/30>`_
37+
or an issue so we can try to find a supported way to serve them.
38+
3239

3340
With PyAPI_FUNC or PyAPI_DATA
3441
-----------------------------
3542

3643
Functions or structures in ``Include/internal/`` defined with
3744
``PyAPI_FUNC`` or ``PyAPI_DATA`` are internal functions which are
3845
exposed only for specific use cases like debuggers and profilers.
46+
Ideally, these should be migrated to the :ref:`unstable-capi`.
3947

4048

4149
With the extern keyword
@@ -53,14 +61,18 @@ Private names
5361
--------------
5462

5563
Any API named with a leading underscore is also considered internal.
56-
There are two main use cases for using such names rather than putting the
57-
definition in ``Include/internal/`` (or directly in a ``.c`` file):
64+
There is currently only one main use case for using such names rather than
65+
putting the definition in :cpy-file:`Include/internal/` (or directly in a ``.c`` file):
66+
67+
* Internal helpers for other public APIs, which users should not call directly.
68+
69+
Note that historically, underscores were used for APIs that are better served by
70+
the :ref:`unstable-capi`:
71+
72+
* “provisional” APIs, included in a Python release to test real-world
73+
usage of new APIs;
74+
* APIs for very specialized uses like JIT compilers.
5875

59-
* Internal helpers for other public API; users should not use these directly;
60-
* “Provisional” API, included in a Python release to test real-world usage
61-
of new API. Such names should be renamed when stabilized; preferably with
62-
a macro aliasing the old name to the new one.
63-
See :pep:`"Finalizing the API" in PEP 590 <590#finalizing-the-api>` for an example.
6476

6577
Internal API Tests
6678
------------------
@@ -134,6 +146,103 @@ When moving existing tests, feel free to replace ``TestError`` with
134146
``PyExc_AssertionError`` unless actually testing custom exceptions.
135147

136148

149+
.. _unstable-capi:
150+
151+
Unstable C API
152+
==============
153+
154+
The unstable C API tier is meant for extensions that need tight integration
155+
with the interpreter, like debuggers and JIT compilers.
156+
Users of this tier may need to change their code with every minor release.
157+
158+
In many ways, this tier is like the general C API:
159+
160+
- it's available when ``Python.h`` is included normally,
161+
- it should be defined in :cpy-file:`Include/cpython/`,
162+
- it requires tests, so we don't break it unintentionally
163+
- it requires docs, so both we and the users,
164+
can agree on the expected behavior,
165+
- it is tested and documented in the same way.
166+
167+
The differences are:
168+
169+
- Names of functions structs, macros, etc. start with the ``PyUnstable_``
170+
prefix. This defines what's in the unstable tier.
171+
- The unstable API can change in minor versions, without any deprecation
172+
period.
173+
- A stability note appears in the docs.
174+
This happens automatically, based on the name
175+
(via :cpy-file:`Doc/tools/extensions/c_annotations.py`).
176+
177+
Despite being “unstable”, there are rules to make sure third-party code can
178+
use this API reliably:
179+
180+
* Changes and removals can be done in minor releases
181+
(:samp:`3.{x}.0`, including Alphas and Betas for :samp:`3.{x}.0`).
182+
* Adding a new unstable API *for an existing feature* is allowed even after
183+
Beta feature freeze, up until the first Release Candidate.
184+
Consensus on the `Core Development Discourse <https://discuss.python.org/c/core-dev/23>`_
185+
is needed in the Beta period.
186+
* Backwards-incompatible changes should make existing C callers fail to compile.
187+
For example, arguments should be added/removed, or a function should be
188+
renamed.
189+
* When moving an API into or out of the Unstable tier, the old name
190+
should continue to be available (but deprecated) until an incompatible
191+
change is made. In other words, while we're allowed to break calling code,
192+
we shouldn't break it *unnecessarily*.
193+
194+
195+
Moving an API from the public tier to Unstable
196+
----------------------------------------------
197+
198+
* Expose the API under its new name, with the ``PyUnstable_`` prefix.
199+
* Make the old name an alias (e.g. a ``static inline`` function calling the
200+
new function).
201+
* Deprecate the old name, typically using :c:macro:`Py_DEPRECATED`.
202+
* Announce the change in the "What's New".
203+
204+
The old name should continue to be available until an incompatible change is
205+
made. Per Python’s backwards compatibility policy (:pep:`387`),
206+
this deprecation needs to last at least two releases
207+
(modulo Steering Council exceptions).
208+
209+
The rules are relaxed for APIs that were introduced in Python versions
210+
before 3.12, when the official Unstable tier was added.
211+
You can make an incompatible change (and remove the old name)
212+
as if the function was already part of the Unstable tier
213+
for APIs introduced before Python 3.12 that are either:
214+
215+
* Documented to be less stable than default.
216+
* Named with a leading underscore.
217+
218+
Moving an API from the private tier to unstable
219+
-----------------------------------------------
220+
221+
* Expose the API under its new name, with the ``PyUnstable_`` prefix.
222+
* If the old name is documented, or widely used externally,
223+
make it an alias and deprecate it (typically with :c:macro:`Py_DEPRECATED`).
224+
It should continue to be available until an incompatible change is made,
225+
as if it was previously public.
226+
227+
This applies even to underscored names. Python wasn't always strict with
228+
the leading underscore.
229+
* Announce the change in What's New.
230+
231+
Moving an API from unstable to public
232+
-------------------------------------
233+
234+
* Expose the API under its new name, without the ``PyUnstable_`` prefix.
235+
* Make the old ``PyUnstable_*`` name be an alias (e.g. a ``static inline``
236+
function calling the new function).
237+
* Announce the change in What's New.
238+
239+
The old name should remain available until the
240+
new public name is deprecated or removed.
241+
There's no need to deprecate the old name (it was unstable to begin with),
242+
but there's also no need to break working code just because some function
243+
is now ready for a wider audience.
244+
245+
137246
Limited API
138247
===========
139248

0 commit comments

Comments
 (0)