-
-
Notifications
You must be signed in to change notification settings - Fork 31k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-91744: Add semi-stable C API tier #91789
Changes from all commits
0185c42
381fc11
23e8a1d
02c5466
e8e1884
a441699
31beafd
132fd8e
7dba38c
74419bd
31ea0db
75abb20
b189c81
911f78a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,9 @@ | |
C API Stability | ||
*************** | ||
|
||
Python's C API is covered by the Backwards Compatibility Policy, :pep:`387`. | ||
While the C API will change with every minor release (e.g. from 3.9 to 3.10), | ||
most changes will be source-compatible, typically by only adding new API. | ||
Unless documented otherwise, Python's C API is covered by the Backwards | ||
Compatibility Policy, :pep:`387`. | ||
Most changes to it are source-compatible (typically by only adding new API). | ||
Changing existing API or removing API is only done after a deprecation period | ||
or to fix serious issues. | ||
|
||
|
@@ -18,8 +18,35 @@ way; see :ref:`stable-abi-platform` below). | |
So, code compiled for Python 3.10.0 will work on 3.10.8 and vice versa, | ||
but will need to be compiled separately for 3.9.x and 3.10.x. | ||
|
||
There are two tiers of C API with different stability expectations, | ||
enabled by specific macros: | ||
|
||
- :c:macro:`Py_USING_SEMI_STABLE_API` exposes API that may change | ||
without deprecation warnings. | ||
- :c:macro:`Py_LIMITED_API` limits exposed API to API that is compatible | ||
across several minor releases. | ||
|
||
These are discussed in more detail below. | ||
|
||
Names prefixed by an underscore, such as ``_Py_InternalState``, | ||
are private API that can change without notice even in patch releases. | ||
If you need to use this API, consider reaching out to | ||
`CPython developers <mailto:[email protected]>`_ to discusss adding | ||
external API for your use case. | ||
|
||
|
||
Semi-stable C API | ||
================= | ||
|
||
.. c:macro:: Py_USING_SEMI_STABLE_API | ||
|
||
Define this macro to access semi-stable API, intended for low-level | ||
tools like debuggers. | ||
This API exposes CPython implementation details, and may change | ||
in every minor release (e.g. from 3.9 to 3.10) without | ||
any deprecation warnings. | ||
Projects that define ``Py_USING_SEMI_STABLE_API`` are expected to follow | ||
CPython development and spend extra effort adjusting to changes. | ||
|
||
|
||
Stable Application Binary Interface | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1405,7 +1405,30 @@ C API Changes | |
be used for ``size``. | ||
(Contributed by Kumar Aditya in :issue:`46608`.) | ||
|
||
* :c:func:`_PyFrameEvalFunction` now takes ``_PyInterpreterFrame*`` | ||
* Introduced the *semi-stable* tier of C API, intended for low-level tools like | ||
debuggers and JIT compilers. | ||
This API may change in each minor release of CPython without deprecation | ||
warnings, and is exposed by defining :c:macro:`Py_USING_SEMI_STABLE_API`. | ||
The folllowing functions and types are part of the semi-stable API. | ||
Using them without defining ``Py_USING_SEMI_STABLE_API`` is deprecated and | ||
will be disallowed in Python 3.12: | ||
|
||
- :c:func:`PyEval_RequestCodeExtraIndex` | ||
- :c:func:`PyCode_GetExtra` | ||
- :c:func:`PyCode_SetExtra` | ||
- :c:func:`PyCode_New` | ||
- :c:func:`PyCode_NewWithPosOnlyArgs`, | ||
- :c:func:`PyInterpreterState_GetEvalFrameFunc` | ||
- :c:func:`PyInterpreterState_SetEvalFrameFunc` | ||
- :c:type:`PyFrameEvalFunction` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe mention also _PyFrameEvalFunction type which is renamed? |
||
Some of these were named with a leading underscore in previous versions; | ||
the old names are available as aliases. | ||
|
||
(Contributed by Petr Viktorin, Victor Stinner and Nick Coghlan in | ||
:gh:`91744`.) | ||
|
||
* :c:func:`PyFrameEvalFunction` now takes ``_PyInterpreterFrame*`` | ||
as its second parameter, instead of ``PyFrameObject*``. | ||
See :pep:`523` for more details of how to use this function pointer type. | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -140,19 +140,7 @@ PyAPI_DATA(PyTypeObject) PyCode_Type; | |||||
#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive) | ||||||
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) | ||||||
|
||||||
/* Public interface */ | ||||||
PyAPI_FUNC(PyCodeObject *) PyCode_New( | ||||||
int, int, int, int, int, PyObject *, PyObject *, | ||||||
PyObject *, PyObject *, PyObject *, PyObject *, | ||||||
PyObject *, PyObject *, PyObject *, int, PyObject *, | ||||||
PyObject *); | ||||||
|
||||||
PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( | ||||||
int, int, int, int, int, int, PyObject *, PyObject *, | ||||||
PyObject *, PyObject *, PyObject *, PyObject *, | ||||||
PyObject *, PyObject *, PyObject *, int, PyObject *, | ||||||
PyObject *); | ||||||
/* same as struct above */ | ||||||
/* See Include/semi-stable/code.h for PyCode_New* */ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that this comment is useful.
Suggested change
|
||||||
|
||||||
/* Creates a new empty code object with the specified source location. */ | ||||||
PyAPI_FUNC(PyCodeObject *) | ||||||
|
@@ -196,12 +184,6 @@ PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); | |||||
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, | ||||||
PyObject *names, PyObject *lnotab); | ||||||
|
||||||
|
||||||
PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, | ||||||
void **extra); | ||||||
PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, | ||||||
void *extra); | ||||||
|
||||||
/* Equivalent to getattr(code, 'co_code') in Python. | ||||||
Returns a strong reference to a bytes object. */ | ||||||
PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code); | ||||||
|
@@ -219,6 +201,11 @@ typedef enum _PyCodeLocationInfoKind { | |||||
PY_CODE_LOCATION_INFO_NONE = 15 | ||||||
} _PyCodeLocationInfoKind; | ||||||
|
||||||
#define Py_UNSTABLE_CODE_H | ||||||
#include "unstable/code.h" | ||||||
#undef Py_UNSTABLE_CODE_H | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to include it in top-level Include/code.h, as done in Include/pystate.h. |
||||||
|
||||||
|
||||||
#ifdef __cplusplus | ||||||
} | ||||||
#endif | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -61,6 +61,10 @@ | |||||||||||||||||||||
# define Py_BUILD_CORE | ||||||||||||||||||||||
#endif | ||||||||||||||||||||||
|
||||||||||||||||||||||
// Expose unstable API when building Python | ||||||||||||||||||||||
#ifdef Py_BUILD_CORE | ||||||||||||||||||||||
#define Py_USING_UNSTABLE_API | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
#endif | ||||||||||||||||||||||
|
||||||||||||||||||||||
/************************************************************************** | ||||||||||||||||||||||
Symbols and macros to supply platform-independent interfaces to basic | ||||||||||||||||||||||
|
@@ -371,6 +375,15 @@ extern "C" { | |||||||||||||||||||||
#define _Py_COMP_DIAG_POP | ||||||||||||||||||||||
#endif | ||||||||||||||||||||||
|
||||||||||||||||||||||
/* _Py_NEWLY_UNSTABLE: Provide deprecation warnings for users that | ||||||||||||||||||||||
* don't opt in to unstable API. | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
#ifdef Py_USING_UNSTABLE_API | ||||||||||||||||||||||
#define _Py_NEWLY_UNSTABLE(VERSION_UNUSED) | ||||||||||||||||||||||
#else | ||||||||||||||||||||||
#define _Py_NEWLY_UNSTABLE(VERSION) Py_DEPRECATED(VERSION) | ||||||||||||||||||||||
#endif | ||||||||||||||||||||||
Comment on lines
+381
to
+385
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
/* _Py_HOT_FUNCTION | ||||||||||||||||||||||
* The hot attribute on a function is used to inform the compiler that the | ||||||||||||||||||||||
* function is a hot spot of the compiled program. The function is optimized | ||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is API repeated on purpose?