[3.12] gh-102304: doc: Add links to Stable ABI and Limited C API (#105345) (#105371)

* gh-102304: doc: Add links to Stable ABI and Limited C API (#105345)

* Add "limited-c-api" and "stable-api" references.
* Rename "stable-abi-list" reference to "limited-api-list".
* Makefile: Document files regenerated by "make regen-limited-abi"
* Remove first empty line in generated files:

  - Lib/test/test_stable_abi_ctypes.py
  - PC/python3dll.c

(cherry picked from commit bae415ad02)

* gh-102304: Fix up Simple ABI doc (GH-105351)

(cherry picked from commit 0202aa002e)
This commit is contained in:
Victor Stinner 2023-06-06 15:11:28 +02:00 committed by GitHub
parent 67b288f8be
commit 82ab13c49a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 53 additions and 42 deletions

View file

@ -887,7 +887,7 @@ because the :ref:`call protocol <call>` takes care of recursion handling.
depth limit. depth limit.
.. versionchanged:: 3.9 .. versionchanged:: 3.9
This function is now also available in the limited API. This function is now also available in the :ref:`limited API <limited-c-api>`.
.. c:function:: void Py_LeaveRecursiveCall(void) .. c:function:: void Py_LeaveRecursiveCall(void)
@ -895,7 +895,7 @@ because the :ref:`call protocol <call>` takes care of recursion handling.
*successful* invocation of :c:func:`Py_EnterRecursiveCall`. *successful* invocation of :c:func:`Py_EnterRecursiveCall`.
.. versionchanged:: 3.9 .. versionchanged:: 3.9
This function is now also available in the limited API. This function is now also available in the :ref:`limited API <limited-c-api>`.
Properly implementing :c:member:`~PyTypeObject.tp_repr` for container types requires Properly implementing :c:member:`~PyTypeObject.tp_repr` for container types requires
special recursion handling. In addition to protecting the stack, special recursion handling. In addition to protecting the stack,

View file

@ -20,9 +20,9 @@ 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 exepectations: There are two tiers of C API with different stability exepectations:
- *Unstable API*, may change in minor versions without a deprecation period. - :ref:`Unstable API <unstable-c-api>`, may change in minor versions without
It is marked by the ``PyUnstable`` prefix in names. a deprecation period. It is marked by the ``PyUnstable`` prefix in names.
- *Limited API*, is compatible across several minor releases. - :ref:`Limited API <limited-c-api>`, is compatible across several minor releases.
When :c:macro:`Py_LIMITED_API` is defined, only this subset is exposed When :c:macro:`Py_LIMITED_API` is defined, only this subset is exposed
from ``Python.h``. from ``Python.h``.
@ -55,19 +55,19 @@ CPython development and spend extra effort adjusting to changes.
Stable Application Binary Interface Stable Application Binary Interface
=================================== ===================================
For simplicity, this document talks about *extensions*, but the Limited API
and Stable ABI work the same way for all uses of the API for example,
embedding Python.
.. _limited-c-api:
Limited C API
-------------
Python 3.2 introduced the *Limited API*, a subset of Python's C API. Python 3.2 introduced the *Limited API*, a subset of Python's C API.
Extensions that only use the Limited API can be Extensions that only use the Limited API can be
compiled once and work with multiple versions of Python. compiled once and work with multiple versions of Python.
Contents of the Limited API are :ref:`listed below <stable-abi-list>`. Contents of the Limited API are :ref:`listed below <limited-api-list>`.
To enable this, Python provides a *Stable ABI*: a set of symbols that will
remain compatible across Python 3.x versions. The Stable ABI contains symbols
exposed in the Limited API, but also other ones for example, functions
necessary to support older versions of the Limited API.
(For simplicity, this document talks about *extensions*, but the Limited API
and Stable ABI work the same way for all uses of the API for example,
embedding Python.)
.. c:macro:: Py_LIMITED_API .. c:macro:: Py_LIMITED_API
@ -87,6 +87,19 @@ embedding Python.)
You can also define ``Py_LIMITED_API`` to ``3``. This works the same as You can also define ``Py_LIMITED_API`` to ``3``. This works the same as
``0x03020000`` (Python 3.2, the version that introduced Limited API). ``0x03020000`` (Python 3.2, the version that introduced Limited API).
.. _stable-abi:
Stable ABI
----------
To enable this, Python provides a *Stable ABI*: a set of symbols that will
remain compatible across Python 3.x versions.
The Stable ABI contains symbols exposed in the :ref:`Limited API
<limited-c-api>`, but also other ones for example, functions necessary to
support older versions of the Limited API.
On Windows, extensions that use the Stable ABI should be linked against On Windows, extensions that use the Stable ABI should be linked against
``python3.dll`` rather than a version-specific library such as ``python3.dll`` rather than a version-specific library such as
``python39.dll``. ``python39.dll``.
@ -131,9 +144,9 @@ Limited API Caveats
------------------- -------------------
Note that compiling with ``Py_LIMITED_API`` is *not* a complete guarantee that Note that compiling with ``Py_LIMITED_API`` is *not* a complete guarantee that
code conforms to the Limited API or the Stable ABI. ``Py_LIMITED_API`` only code conforms to the :ref:`Limited API <limited-c-api>` or the :ref:`Stable ABI
covers definitions, but an API also includes other issues, such as expected <stable-abi>`. ``Py_LIMITED_API`` only covers definitions, but an API also
semantics. includes other issues, such as expected semantics.
One issue that ``Py_LIMITED_API`` does not guard against is calling a function One issue that ``Py_LIMITED_API`` does not guard against is calling a function
with arguments that are invalid in a lower Python version. with arguments that are invalid in a lower Python version.
@ -166,9 +179,9 @@ Platform Considerations
======================= =======================
ABI stability depends not only on Python, but also on the compiler used, ABI stability depends not only on Python, but also on the compiler used,
lower-level libraries and compiler options. For the purposes of the Stable ABI, lower-level libraries and compiler options. For the purposes of
these details define a “platform”. They usually depend on the OS the :ref:`Stable ABI <stable-abi>`, these details define a “platform”. They
type and processor architecture usually depend on the OS type and processor architecture
It is the responsibility of each particular distributor of Python It is the responsibility of each particular distributor of Python
to ensure that all Python versions on a particular platform are built to ensure that all Python versions on a particular platform are built
@ -177,12 +190,12 @@ This is the case with Windows and macOS releases from ``python.org`` and many
third-party distributors. third-party distributors.
.. _stable-abi-list: .. _limited-api-list:
Contents of Limited API Contents of Limited API
======================= =======================
Currently, the Limited API includes the following items: Currently, the :ref:`Limited API <limited-c-api>` includes the following items:
.. limited-api-list:: .. limited-api-list::

View file

@ -288,7 +288,7 @@ There are these calling conventions:
.. versionchanged:: 3.10 .. versionchanged:: 3.10
``METH_FASTCALL`` is now part of the stable ABI. ``METH_FASTCALL`` is now part of the :ref:`stable ABI <stable-abi>`.
.. data:: METH_FASTCALL | METH_KEYWORDS .. data:: METH_FASTCALL | METH_KEYWORDS

View file

@ -42,7 +42,7 @@ Type Objects
Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily
meant for use with ``Py_LIMITED_API``; the individual flag bits are meant for use with ``Py_LIMITED_API``; the individual flag bits are
guaranteed to be stable across Python releases, but access to guaranteed to be stable across Python releases, but access to
:c:member:`~PyTypeObject.tp_flags` itself is not part of the limited API. :c:member:`~PyTypeObject.tp_flags` itself is not part of the :ref:`limited API <limited-c-api>`.
.. versionadded:: 3.2 .. versionadded:: 3.2
@ -472,7 +472,7 @@ The following functions and structs are used to create
.. versionchanged:: 3.11 .. versionchanged:: 3.11
:c:member:`~PyBufferProcs.bf_getbuffer` and :c:member:`~PyBufferProcs.bf_getbuffer` and
:c:member:`~PyBufferProcs.bf_releasebuffer` are now available :c:member:`~PyBufferProcs.bf_releasebuffer` are now available
under the limited API. under the :ref:`limited API <limited-c-api>`.
.. c:member:: void *pfunc .. c:member:: void *pfunc

View file

@ -2150,7 +2150,7 @@ This results in types that are limited relative to types defined in Python:
include any subinterpreter-specific state. include any subinterpreter-specific state.
Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API
<stable>` as an opaque struct, any extension modules using static types must be <limited-c-api>` as an opaque struct, any extension modules using static types must be
compiled for a specific Python minor version. compiled for a specific Python minor version.

View file

@ -992,7 +992,7 @@ These are the UTF-8 codec APIs:
The return type is now ``const char *`` rather of ``char *``. The return type is now ``const char *`` rather of ``char *``.
.. versionchanged:: 3.10 .. versionchanged:: 3.10
This function is a part of the :ref:`limited API <stable>`. This function is a part of the :ref:`limited API <limited-c-api>`.
.. c:function:: const char* PyUnicode_AsUTF8(PyObject *unicode) .. c:function:: const char* PyUnicode_AsUTF8(PyObject *unicode)

View file

@ -461,7 +461,7 @@ Module State Access from Slot Methods, Getters and Setters
.. After adding to limited API: .. After adding to limited API:
If you use the :ref:`limited API <stable>, If you use the :ref:`limited API <limited-c-api>`,
you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI
compatibility with earlier versions. compatibility with earlier versions.

View file

@ -803,7 +803,7 @@ The :mod:`test.support` module defines the following functions:
.. decorator:: requires_limited_api .. decorator:: requires_limited_api
Decorator for only running the test if :ref:`Limited C API <stable>` Decorator for only running the test if :ref:`Limited C API <limited-c-api>`
is available. is available.

View file

@ -2650,7 +2650,7 @@ Removed
* :c:func:`PyMarshal_WriteObjectToString` * :c:func:`PyMarshal_WriteObjectToString`
* the ``Py_MARSHAL_VERSION`` macro * the ``Py_MARSHAL_VERSION`` macro
These are not part of the :ref:`limited API <stable-abi-list>`. These are not part of the :ref:`limited API <limited-api-list>`.
(Contributed by Victor Stinner in :issue:`45474`.) (Contributed by Victor Stinner in :issue:`45474`.)

View file

@ -1580,7 +1580,7 @@ New Features
(Contributed by Petr Viktorin in :gh:`103509`.) (Contributed by Petr Viktorin in :gh:`103509`.)
* Added the new limited C API function :c:func:`PyType_FromMetaclass`, * Added the new :ref:`limited C API <limited-c-api>` function :c:func:`PyType_FromMetaclass`,
which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using
an additional metaclass argument. an additional metaclass argument.
(Contributed by Wenzel Jakob in :gh:`93012`.) (Contributed by Wenzel Jakob in :gh:`93012`.)

View file

@ -1,5 +1,4 @@
# Generated by Tools/build/stable_abi.py
# Generated by Tools/scripts/stable_abi.py
"""Test that all symbols of the Stable ABI are accessible using ctypes """Test that all symbols of the Stable ABI are accessible using ctypes
""" """

View file

@ -4980,7 +4980,7 @@ Removed documentation for the removed ``PyParser_*`` C API.
.. nonce: fy0AXK .. nonce: fy0AXK
.. section: C API .. section: C API
The list in :ref:`stable-abi-list` now shows the public name The list in :ref:`limited-api-list` now shows the public name
:c:struct:`PyFrameObject` rather than ``_frame``. The non-existing entry :c:struct:`PyFrameObject` rather than ``_frame``. The non-existing entry
``_node`` no longer appears in the list. ``_node`` no longer appears in the list.

View file

@ -1234,7 +1234,7 @@ defined:
* :c:func:`PyMarshal_WriteObjectToString` * :c:func:`PyMarshal_WriteObjectToString`
* the ``Py_MARSHAL_VERSION`` macro * the ``Py_MARSHAL_VERSION`` macro
These are not part of the :ref:`limited API <stable-abi-list>`. These are not part of the :ref:`limited API <limited-api-list>`.
Patch by Victor Stinner. Patch by Victor Stinner.

View file

@ -1,4 +1,4 @@
// Generated by Tools/scripts/stable_abi.py // Generated by Tools/build/stable_abi.py
// Add an entry in dict `result` for each Stable ABI feature macro. // Add an entry in dict `result` for each Stable ABI feature macro.

1
PC/python3dll.c generated
View file

@ -1,4 +1,3 @@
/* Re-export stable Python ABI */ /* Re-export stable Python ABI */
/* Generated by Tools/build/stable_abi.py */ /* Generated by Tools/build/stable_abi.py */

View file

@ -183,7 +183,7 @@ def generator(var_name, default_path):
def gen_python3dll(manifest, args, outfile): def gen_python3dll(manifest, args, outfile):
"""Generate/check the source for the Windows stable ABI library""" """Generate/check the source for the Windows stable ABI library"""
write = partial(print, file=outfile) write = partial(print, file=outfile)
content = f""" content = f"""\
/* Re-export stable Python ABI */ /* Re-export stable Python ABI */
/* Generated by {SCRIPT_NAME} */ /* Generated by {SCRIPT_NAME} */
@ -267,8 +267,8 @@ def gen_doc_annotations(manifest, args, outfile):
def gen_ctypes_test(manifest, args, outfile): def gen_ctypes_test(manifest, args, outfile):
"""Generate/check the ctypes-based test for exported symbols""" """Generate/check the ctypes-based test for exported symbols"""
write = partial(print, file=outfile) write = partial(print, file=outfile)
write(textwrap.dedent(''' write(textwrap.dedent(f'''\
# Generated by Tools/scripts/stable_abi.py # Generated by {SCRIPT_NAME}
"""Test that all symbols of the Stable ABI are accessible using ctypes """Test that all symbols of the Stable ABI are accessible using ctypes
""" """
@ -341,7 +341,7 @@ def gen_ctypes_test(manifest, args, outfile):
def gen_testcapi_feature_macros(manifest, args, outfile): def gen_testcapi_feature_macros(manifest, args, outfile):
"""Generate/check the stable ABI list for documentation annotations""" """Generate/check the stable ABI list for documentation annotations"""
write = partial(print, file=outfile) write = partial(print, file=outfile)
write('// Generated by Tools/scripts/stable_abi.py') write(f'// Generated by {SCRIPT_NAME}')
write() write()
write('// Add an entry in dict `result` for each Stable ABI feature macro.') write('// Add an entry in dict `result` for each Stable ABI feature macro.')
write() write()