PEP 757: minor edits (#3962)
This commit is contained in:
parent
5ac83c8cb7
commit
7bd5c21ca1
|
@ -62,6 +62,7 @@ intersphinx_mapping = {
|
||||||
"py3.11": ("https://docs.python.org/3.11/", None),
|
"py3.11": ("https://docs.python.org/3.11/", None),
|
||||||
"py3.12": ("https://docs.python.org/3.12/", None),
|
"py3.12": ("https://docs.python.org/3.12/", None),
|
||||||
"py3.13": ("https://docs.python.org/3.13/", None),
|
"py3.13": ("https://docs.python.org/3.13/", None),
|
||||||
|
"py3.14": ("https://docs.python.org/3.14/", None),
|
||||||
}
|
}
|
||||||
intersphinx_disabled_reftypes = []
|
intersphinx_disabled_reftypes = []
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ Title: C API to import-export Python integers
|
||||||
Author: Sergey B Kirpichev <skirpichev@gmail.com>,
|
Author: Sergey B Kirpichev <skirpichev@gmail.com>,
|
||||||
Victor Stinner <vstinner@python.org>
|
Victor Stinner <vstinner@python.org>
|
||||||
PEP-Delegate: C API Working Group
|
PEP-Delegate: C API Working Group
|
||||||
|
Discussions-To: https://discuss.python.org/t/63895
|
||||||
Status: Draft
|
Status: Draft
|
||||||
Type: Standards Track
|
Type: Standards Track
|
||||||
Created: 13-Sep-2024
|
Created: 13-Sep-2024
|
||||||
Python-Version: 3.14
|
Python-Version: 3.14
|
||||||
|
Post-History: `14-Sep-2024 <https://discuss.python.org/t/63895>`__
|
||||||
|
|
||||||
.. highlight:: c
|
.. highlight:: c
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ Python-Version: 3.14
|
||||||
Abstract
|
Abstract
|
||||||
========
|
========
|
||||||
|
|
||||||
Add a new C API to import and export Python integers, ``int`` objects:
|
Add a new C API to import and export Python integers, :class:`int` objects:
|
||||||
especially ``PyLongWriter_Create()`` and ``PyLong_AsDigitArray()``
|
especially ``PyLongWriter_Create()`` and ``PyLong_AsDigitArray()``
|
||||||
functions.
|
functions.
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ Projects such as `gmpy2 <https://github.com/aleaxit/gmpy>`_, `SAGE
|
||||||
<https://github.com/flintlib/python-flint>`_ access directly Python
|
<https://github.com/flintlib/python-flint>`_ access directly Python
|
||||||
"internals" (the ``PyLongObject`` structure) or use an inefficient
|
"internals" (the ``PyLongObject`` structure) or use an inefficient
|
||||||
temporary format (hex strings for Python-FLINT) to import and
|
temporary format (hex strings for Python-FLINT) to import and
|
||||||
export Python ``int`` objects. The Python ``int`` implementation
|
export Python :class:`int` objects. The Python :class:`int` implementation
|
||||||
changed in Python 3.12 to add a tag and "compact values".
|
changed in Python 3.12 to add a tag and "compact values".
|
||||||
|
|
||||||
In the 3.13 alpha 1 release, the private undocumented ``_PyLong_New()``
|
In the 3.13 alpha 1 release, the private undocumented ``_PyLong_New()``
|
||||||
|
@ -75,9 +77,11 @@ Data needed by `GMP <https://gmplib.org/>`_-like import-export functions.
|
||||||
PyLong_GetNativeLayout()
|
PyLong_GetNativeLayout()
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``const PyLongLayout* PyLong_GetNativeLayout(void)``.
|
API::
|
||||||
|
|
||||||
Get the native layout of Python ``int`` objects.
|
const PyLongLayout* PyLong_GetNativeLayout(void)
|
||||||
|
|
||||||
|
Get the native layout of Python :class:`int` objects.
|
||||||
|
|
||||||
|
|
||||||
Export API
|
Export API
|
||||||
|
@ -109,21 +113,23 @@ On CPython 3.14, no memory copy is needed, it's just a thin wrapper to
|
||||||
expose Python int internal digits array.
|
expose Python int internal digits array.
|
||||||
|
|
||||||
``PyLong_DigitArray.obj`` stores a strong reference to the Python
|
``PyLong_DigitArray.obj`` stores a strong reference to the Python
|
||||||
``int`` object to make sure that that structure remains valid until
|
:class:`int` object to make sure that that structure remains valid until
|
||||||
``PyLong_FreeDigitArray()`` is called.
|
``PyLong_FreeDigitArray()`` is called.
|
||||||
|
|
||||||
|
|
||||||
PyLong_AsDigitArray()
|
PyLong_AsDigitArray()
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``int PyLong_AsDigitArray(PyObject *obj, PyLong_DigitArray *array)``.
|
API::
|
||||||
|
|
||||||
Export a Python ``int`` object as a digits array.
|
int PyLong_AsDigitArray(PyObject *obj, PyLong_DigitArray *array)
|
||||||
|
|
||||||
|
Export a Python :class:`int` object as a digits array.
|
||||||
|
|
||||||
On success, set *\*array* and return 0.
|
On success, set *\*array* and return 0.
|
||||||
On error, set an exception and return -1.
|
On error, set an exception and return -1.
|
||||||
|
|
||||||
This function always succeeds if *obj* is a Python ``int`` object or a
|
This function always succeeds if *obj* is a Python :class:`int` object or a
|
||||||
subclass.
|
subclass.
|
||||||
|
|
||||||
``PyLong_FreeDigitArray()`` must be called once done with using
|
``PyLong_FreeDigitArray()`` must be called once done with using
|
||||||
|
@ -133,7 +139,9 @@ subclass.
|
||||||
PyLong_FreeDigitArray()
|
PyLong_FreeDigitArray()
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``void PyLong_FreeDigitArray(PyLong_DigitArray *array)``.
|
API::
|
||||||
|
|
||||||
|
void PyLong_FreeDigitArray(PyLong_DigitArray *array)
|
||||||
|
|
||||||
Release the export *array* created by ``PyLong_AsDigitArray()``.
|
Release the export *array* created by ``PyLong_AsDigitArray()``.
|
||||||
|
|
||||||
|
@ -164,7 +172,9 @@ convert the object to a compact integer if needed.
|
||||||
PyLongWriter_Create()
|
PyLongWriter_Create()
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``PyLongWriter* PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)``.
|
API::
|
||||||
|
|
||||||
|
PyLongWriter* PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)
|
||||||
|
|
||||||
Create a ``PyLongWriter``.
|
Create a ``PyLongWriter``.
|
||||||
|
|
||||||
|
@ -177,7 +187,7 @@ On error, set an exception and return ``NULL``.
|
||||||
greater than or equal to 0.
|
greater than or equal to 0.
|
||||||
|
|
||||||
The caller must initialize the digits array *digits* and then call
|
The caller must initialize the digits array *digits* and then call
|
||||||
``PyLongWriter_Finish()`` to get a Python ``int``. Digits must be
|
``PyLongWriter_Finish()`` to get a Python :class:`int`. Digits must be
|
||||||
in the range [``0``; ``PyLong_BASE - 1``]. Unused digits must be set to
|
in the range [``0``; ``PyLong_BASE - 1``]. Unused digits must be set to
|
||||||
``0``.
|
``0``.
|
||||||
|
|
||||||
|
@ -185,18 +195,22 @@ in the range [``0``; ``PyLong_BASE - 1``]. Unused digits must be set to
|
||||||
PyLongWriter_Finish()
|
PyLongWriter_Finish()
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``PyObject* PyLongWriter_Finish(PyLongWriter *writer)``.
|
API::
|
||||||
|
|
||||||
|
PyObject* PyLongWriter_Finish(PyLongWriter *writer)
|
||||||
|
|
||||||
Finish a ``PyLongWriter`` created by ``PyLongWriter_Create()``.
|
Finish a ``PyLongWriter`` created by ``PyLongWriter_Create()``.
|
||||||
|
|
||||||
On success, return a Python ``int`` object.
|
On success, return a Python :class:`int` object.
|
||||||
On error, set an exception and return ``NULL``.
|
On error, set an exception and return ``NULL``.
|
||||||
|
|
||||||
|
|
||||||
PyLongWriter_Discard()
|
PyLongWriter_Discard()
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
API: ``void PyLongWriter_Discard(PyLongWriter *writer)``.
|
API::
|
||||||
|
|
||||||
|
void PyLongWriter_Discard(PyLongWriter *writer)
|
||||||
|
|
||||||
Discard the internal object and destroy the writer instance.
|
Discard the internal object and destroy the writer instance.
|
||||||
|
|
||||||
|
@ -211,12 +225,11 @@ performance overhead on small integers.
|
||||||
For small integers of a few digits (for example, 1 or 2 digits), existing APIs
|
For small integers of a few digits (for example, 1 or 2 digits), existing APIs
|
||||||
can be used. Examples to import / export:
|
can be used. Examples to import / export:
|
||||||
|
|
||||||
* ``PyLong_FromUInt64()`` / ``PyLong_AsUInt64()``;
|
* :external+py3.14:c:func:`PyLong_FromUInt64()` / :external+py3.14:c:func:`PyLong_AsUInt64()`;
|
||||||
* ``PyLong_FromLong()`` / ``PyLong_AsLong()`` or ``PyLong_AsInt()``;
|
* :c:func:`PyLong_FromLong()` / :c:func:`PyLong_AsLong()` or :c:func:`PyLong_AsInt()`;
|
||||||
* ``PyUnstable_PyLong_IsCompact()`` and
|
* :external+py3.13:c:func:`PyUnstable_Long_IsCompact()` and
|
||||||
``PyUnstable_PyLong_CompactValue()``;
|
:external+py3.13:c:func:`PyUnstable_Long_CompactValue()`;
|
||||||
* ``PyLong_FromNativeBytes()`` / ``PyLong_AsNativeBytes()``;
|
* :c:func:`PyLong_FromNativeBytes()` / :c:func:`PyLong_AsNativeBytes()`;
|
||||||
* etc.
|
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
@ -362,14 +375,21 @@ There is no impact on the backward compatibility, only new APIs are
|
||||||
added.
|
added.
|
||||||
|
|
||||||
|
|
||||||
Open Question
|
Open Questions
|
||||||
=============
|
==============
|
||||||
|
|
||||||
* Should we add *digits_order* and *endian* members to ``sys.int_info``
|
* Should we add *digits_order* and *endian* members to :data:`sys.int_info`
|
||||||
and remove ``PyLong_GetNativeLayout()``? The
|
and remove ``PyLong_GetNativeLayout()``? The
|
||||||
``PyLong_GetNativeLayout()`` function returns a C structure
|
``PyLong_GetNativeLayout()`` function returns a C structure
|
||||||
which is more convenient to use in C than ``sys.int_info`` which uses
|
which is more convenient to use in C than :data:`sys.int_info` which uses
|
||||||
Python objects.
|
Python objects.
|
||||||
|
* Currenly, all required information for :class:`int` import/export is
|
||||||
|
already available via :c:func:`PyLong_GetInfo()` or :data:`sys.int_info`.
|
||||||
|
Native endianness of "digits" and current order of digits (least
|
||||||
|
significant digit first) --- is a common denominator of all libraries
|
||||||
|
for aribitrary precision integer arithmetic. So, shouldn't we just remove
|
||||||
|
from API both ``PyLongLayout`` and ``PyLong_GetNativeLayout()`` (which
|
||||||
|
is actually just a minor convenience)?
|
||||||
|
|
||||||
|
|
||||||
Rejected Ideas
|
Rejected Ideas
|
||||||
|
|
Loading…
Reference in New Issue