44Changing 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
991. 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
2022The compatibility guarantees for public C API are explained in the
2123user 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
3032While internal API can be changed at any time, it's still good to keep it
3133stable: 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
3340With PyAPI_FUNC or PyAPI_DATA
3441-----------------------------
3542
3643Functions or structures in ``Include/internal/ `` defined with
3744``PyAPI_FUNC `` or ``PyAPI_DATA `` are internal functions which are
3845exposed only for specific use cases like debuggers and profilers.
46+ Ideally, these should be migrated to the :ref: `unstable-capi `.
3947
4048
4149With the extern keyword
@@ -53,14 +61,18 @@ Private names
5361--------------
5462
5563Any 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
6577Internal 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+
137246Limited API
138247===========
139248
0 commit comments