-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
gh-137210: Add a struct, slot & function for checking an extension's ABI #137212
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
894ef3d
72349ba
3b6aa96
c015606
c5740af
da293e3
44df416
feb428d
aa1eb4a
b628d7d
4800a5d
4c9e918
1b18761
814ac60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,9 +2,9 @@ | |
|
||
.. _stable: | ||
|
||
*************** | ||
C API Stability | ||
*************** | ||
*********************** | ||
C API and ABI Stability | ||
*********************** | ||
|
||
Unless documented otherwise, Python's C API is covered by the Backwards | ||
Compatibility Policy, :pep:`387`. | ||
|
@@ -199,6 +199,156 @@ This is the case with Windows and macOS releases from ``python.org`` and many | |
third-party distributors. | ||
|
||
|
||
ABI Checking | ||
============ | ||
|
||
.. versionadded:: next | ||
|
||
Python includes a rudimentary check for ABI compatibility. | ||
|
||
This check is not comprehensive. | ||
It only guards against common cases of incompatible modules being | ||
installed for the wrong interpreter. | ||
It also does not take :ref:`platform incompatibilities <stable-abi-platform>` | ||
into account. | ||
It can only be done after an extension is successfully loaded. | ||
|
||
Despite these limitations, it is recommended that extension modules use this | ||
mechanism, so that detectable incompatibilities raise exceptions rather than | ||
crash. | ||
|
||
Most modules can use this check via the :c:data:`Py_mod_abi` | ||
slot and the :c:macro:`PyABIInfo_VAR` macro. | ||
The full API is described below for advanced use cases. | ||
|
||
.. c:function:: int PyABIInfo_Check(PyABIInfo *info, const char *module_name) | ||
|
||
Verify that the given *info* is compatible with the currently running | ||
interpreter. | ||
|
||
Return 0 on success. On failure, raise an exception and return -1. | ||
|
||
If the ABI is incompatible, the raised exception will be :py:exc:`ImportError`. | ||
|
||
The *module_name* argument can be ``NULL``, or point to a NUL-terminated | ||
UTF-8-encoded string used for error messages. | ||
|
||
Note that if *info* describes the ABI taht the current code uses (as defined | ||
by :c:macro:`PyABIInfo_VAR`, for example), using any other Python C API | ||
may lead to crashes. | ||
In particular, it is not safe to examine the raised exception. | ||
|
||
.. versionadded:: next | ||
|
||
.. c:macro:: PyABIInfo_VAR(NAME) | ||
|
||
Define a static :c:struct:`PyABIInfo` variable with the given *NAME* that | ||
describes the ABI that the current code will use. | ||
This macro expands to: | ||
|
||
.. code-block:: c | ||
|
||
static PyABIInfo NAME = { | ||
1, 0, | ||
PyABIInfo_DEFAULT_FLAGS, | ||
PY_VERSION_HEX, | ||
PyABIInfo_DEFAULT_ABI_VERSION | ||
} | ||
|
||
.. versionadded:: next | ||
|
||
.. c:type:: PyABIInfo | ||
|
||
.. c:member:: uint8_t PyABIInfo.abiinfo_major_version | ||
|
||
The major version of :c:struct:`PyABIInfo`. Can be set to: | ||
|
||
* ``0`` to skip all checking, or | ||
* ``1`` to specify this version of :c:struct:`!PyABIInfo`. | ||
|
||
.. c:member:: uint8_t PyABIInfo.abiinfo_minor_version | ||
|
||
The major version of :c:struct:`PyABIInfo`. | ||
Must be set to ``0``; larger values are reserved for backwards-compatible | ||
future versions of :c:struct:`!PyABIInfo`. | ||
|
||
.. c:member:: uint16_t PyABIInfo.flags | ||
|
||
.. c:namespace:: NULL | ||
|
||
This field is usually set to the following macro: | ||
|
||
.. c:macro:: PyABIInfo_DEFAULT_FLAGS | ||
|
||
Default flags, based on current values of macros such as | ||
:c:macro:`Py_LIMITED_API` and :c:macro:`Py_GIL_DISABLED`. | ||
|
||
Alternately, the field can be set to to the following flags, combined | ||
by bitwise OR. | ||
Unused bits must be set to zero. | ||
|
||
ABI variant -- one of: | ||
|
||
.. c:macro:: PyABIInfo_STABLE | ||
|
||
Specifies that the stable ABI is used. | ||
|
||
.. c:macro:: PyABIInfo_INTERNAL | ||
|
||
Specifies ABI specific to a particular build of CPython. | ||
Internal use only. | ||
|
||
Free-threading compatibility -- one of: | ||
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. We're still planning to get rid of these options once FT is merged, right? Maybe we ought to use 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. How would you encode being compatible with both GIL and FT? 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. IMO, we can remove them when there are no GIL-only extensions around any more. That would be a lot of time after FT is the only option. |
||
|
||
.. c:macro:: PyABIInfo_FREETHREADED | ||
|
||
Specifies ABI compatible with free-threading builds of CPython. | ||
(That is, ones compiled with :option:`--disable-gil`; with ``t`` | ||
in :py:data:`sys.abiflags`) | ||
|
||
.. c:macro:: PyABIInfo_GIL | ||
|
||
Specifies ABI compatible with non-free-threading builds of CPython | ||
(ones compiled *without* :option:`--disable-gil`). | ||
|
||
.. c:macro:: PyABIInfo_FREETHREADING_AGNOSTIC | ||
|
||
Specifies ABI compatible with both free-threading and non-free-threading | ||
builds. | ||
|
||
.. c:member:: uint32_t PyABIInfo.build_version | ||
|
||
The version of the Python headers used to build the code, in the format | ||
used by :c:macro:`PY_VERSION_HEX`. | ||
|
||
This can be set to ``0`` to skip any checks related to this field. | ||
This option is meant mainly for projects that do not use the CPython | ||
headers directly, and do not emulate a specific version of them. | ||
|
||
.. c:member:: uint32_t PyABIInfo.abi_version | ||
|
||
The ABI version. | ||
|
||
For the Stable ABI, this field should be the value of | ||
:c:macro:`Py_LIMITED_API` | ||
(except if :c:macro:`Py_LIMITED_API` is ``3``; use | ||
:c:expr:`Py_PACK_VERSION(3, 2)` in that case). | ||
Comment on lines
+329
to
+330
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. Seems easier for us to just check this on our side than to expect users to get it right? 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. And isn't the legacy value 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. Well, users should use The legacy value is 3. (Not that it matters that much; it's always compared to a Python version.) |
||
|
||
Otherwise, it should be set to :c:macro:`PY_VERSION_HEX`. | ||
|
||
It can also be set to ``0`` to skip any checks related to this field. | ||
|
||
.. c:namespace:: NULL | ||
|
||
.. c:macro:: PyABIInfo_DEFAULT_ABI_VERSION | ||
|
||
The value that should be used for this field, based on current | ||
values of macros such as :c:macro:`Py_LIMITED_API`, | ||
:c:macro:`PY_VERSION_HEX` and :c:macro:`Py_GIL_DISABLED`. | ||
|
||
.. versionadded:: next | ||
|
||
|
||
.. _limited-api-list: | ||
|
||
Contents of Limited API | ||
|
Uh oh!
There was an error while loading. Please reload this page.