| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -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`. | ||
| Expand Down Expand Up | @@ -199,6 +199,162 @@ | |
| 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, for example like this: | ||
|
|
||
| .. code-block:: c | ||
|
|
||
| PyABIInfo_VAR(abi_info); | ||
|
|
||
| static PyModuleDef_Slot mymodule_slots[] = { | ||
| {Py_mod_abi, &abi_info}, | ||
| ... | ||
| }; | ||
|
|
||
|
|
||
| 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 that 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 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 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 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: | ||
|
|
||
| .. 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:member:: uint32_t 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 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 thread
Comment on lines
+340
to
+341
Copy link
Copy Markdown
Member
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySeems easier for us to just check this on our side than to expect users to get it right?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAnd isn't the legacy value 1 rather than 3?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWell, users should use PyABIInfo_DEFAULT_ABI_VERSION or PyABIInfo_VAR -- those are our side too. The legacy value is 3. (Not that it matters that much; it's always compared to a Python version.)
Sorry, something went wrong.
All reactions
|
||
|
|
||
| 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 | ||
| Expand Down | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -134,6 +134,72 @@ PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, | |
|
|
||
| #endif /* New in 3.5 */ | ||
|
|
||
| /* ABI info & checking (new in 3.15) */ | ||
| #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030f0000 | ||
| typedef struct PyABIInfo { | ||
| uint8_t abiinfo_major_version; | ||
| uint8_t abiinfo_minor_version; | ||
| uint16_t flags; | ||
| uint32_t build_version; | ||
| uint32_t abi_version; | ||
| } PyABIInfo; | ||
| #define PyABIInfo_STABLE 0x0001 | ||
| #define PyABIInfo_GIL 0x0002 | ||
| #define PyABIInfo_FREETHREADED 0x0004 | ||
| #define PyABIInfo_INTERNAL 0x0008 | ||
|
|
||
| #define PyABIInfo_FREETHREADING_AGNOSTIC (PyABIInfo_GIL|PyABIInfo_FREETHREADED) | ||
|
Comment thread
Copy link
Copy Markdown
Member
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIs there any reason this wasn't documented?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThanks, good catch! This should probably not have been added right now :/
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
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. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualitySounds good, I'll just mark it as tracked by either PEP.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| PyAPI_FUNC(int) PyABIInfo_Check(PyABIInfo *info, const char *module_name); | ||
|
|
||
| // Define the defaults | ||
| #ifdef Py_LIMITED_API | ||
| #define _PyABIInfo_DEFAULT_FLAG_STABLE PyABIInfo_STABLE | ||
| #if Py_LIMITED_API == 3 | ||
| #define PyABIInfo_DEFAULT_ABI_VERSION _Py_PACK_VERSION(3, 2) | ||
| #else | ||
| #define PyABIInfo_DEFAULT_ABI_VERSION Py_LIMITED_API | ||
| #endif | ||
| #else | ||
| #define _PyABIInfo_DEFAULT_FLAG_STABLE 0 | ||
| #define PyABIInfo_DEFAULT_ABI_VERSION PY_VERSION_HEX | ||
| #endif | ||
| #if defined(Py_LIMITED_API) && defined(_Py_OPAQUE_PYOBJECT) | ||
| #define _PyABIInfo_DEFAULT_FLAG_FT PyABIInfo_FREETHREADING_AGNOSTIC | ||
| #elif defined(Py_GIL_DISABLED) | ||
| #define _PyABIInfo_DEFAULT_FLAG_FT PyABIInfo_FREETHREADED | ||
| #else | ||
| #define _PyABIInfo_DEFAULT_FLAG_FT PyABIInfo_GIL | ||
| #endif | ||
| #if defined(Py_BUILD_CORE) | ||
| #define _PyABIInfo_DEFAULT_FLAG_INTERNAL PyABIInfo_INTERNAL | ||
| #else | ||
| #define _PyABIInfo_DEFAULT_FLAG_INTERNAL 0 | ||
| #endif | ||
|
|
||
| #define PyABIInfo_DEFAULT_FLAGS ( \ | ||
| _PyABIInfo_DEFAULT_FLAG_STABLE \ | ||
| | _PyABIInfo_DEFAULT_FLAG_FT \ | ||
| | _PyABIInfo_DEFAULT_FLAG_INTERNAL \ | ||
| ) \ | ||
| ///////////////////////////////////////////////////////// | ||
|
|
||
| #define _PyABIInfo_DEFAULT() { \ | ||
| 1, 0, \ | ||
| PyABIInfo_DEFAULT_FLAGS, \ | ||
| PY_VERSION_HEX, \ | ||
| PyABIInfo_DEFAULT_ABI_VERSION } \ | ||
| ///////////////////////////////////////////////////////// | ||
|
|
||
| #define PyABIInfo_VAR(NAME) \ | ||
| static PyABIInfo NAME = _PyABIInfo_DEFAULT; | ||
|
|
||
| #undef _PyABIInfo_DEFAULT_STABLE | ||
| #undef _PyABIInfo_DEFAULT_FT | ||
| #undef _PyABIInfo_DEFAULT_INTERNAL | ||
|
|
||
| #endif /* ABI info (new in 3.15) */ | ||
|
|
||
| #ifndef Py_LIMITED_API | ||
| # define Py_CPYTHON_MODSUPPORT_H | ||
| # include "cpython/modsupport.h" | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWe're still planning to get rid of these options once FT is merged, right? Maybe we ought to use abiflags here (i.e. a string) instead, for future extensibility? This isn't going to be checked anywhere that it needs to be bitflags.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityHow would you encode being compatible with both GIL and FT?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIMO, 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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.