gh-143869: Add PEP 757 functions to the limited API (#143906)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
This commit is contained in:
Sergey B Kirpichev
2026-01-21 16:47:14 +03:00
committed by GitHub
parent 4ef30a5871
commit 4c7ec78092
8 changed files with 98 additions and 45 deletions
+6 -6
View File
@@ -687,7 +687,7 @@ Export API
.. versionadded:: 3.14
.. c:struct:: PyLongLayout
.. c:type:: PyLongLayout
Layout of an array of "digits" ("limbs" in the GMP terminology), used to
represent absolute value for arbitrary precision integers.
@@ -727,7 +727,7 @@ Export API
Get the native layout of Python :class:`int` objects.
See the :c:struct:`PyLongLayout` structure.
See the :c:type:`PyLongLayout` structure.
The function must not be called before Python initialization nor after
Python finalization. The returned layout is valid until Python is
@@ -735,7 +735,7 @@ Export API
in a process, and so it can be cached.
.. c:struct:: PyLongExport
.. c:type:: PyLongExport
Export of a Python :class:`int` object.
@@ -769,7 +769,7 @@ Export API
Export a Python :class:`int` object.
*export_long* must point to a :c:struct:`PyLongExport` structure allocated
*export_long* must point to a :c:type:`PyLongExport` structure allocated
by the caller. It must not be ``NULL``.
On success, fill in *\*export_long* and return ``0``.
@@ -799,7 +799,7 @@ The :c:type:`PyLongWriter` API can be used to import an integer.
.. versionadded:: 3.14
.. c:struct:: PyLongWriter
.. c:type:: PyLongWriter
A Python :class:`int` writer instance.
@@ -827,7 +827,7 @@ The :c:type:`PyLongWriter` API can be used to import an integer.
The layout of *digits* is described by :c:func:`PyLong_GetNativeLayout`.
Digits must be in the range [``0``; ``(1 << bits_per_digit) - 1``]
(where the :c:struct:`~PyLongLayout.bits_per_digit` is the number of bits
(where the :c:type:`~PyLongLayout.bits_per_digit` is the number of bits
per digit).
Any unused most significant digits must be set to ``0``.
+9
View File
@@ -389,8 +389,14 @@ func,PyList_SetSlice,3.2,,
func,PyList_Size,3.2,,
func,PyList_Sort,3.2,,
data,PyList_Type,3.2,,
type,PyLongExport,3.15,,full-abi
type,PyLongLayout,3.15,,full-abi
type,PyLongObject,3.2,,opaque
data,PyLongRangeIter_Type,3.2,,
type,PyLongWriter,3.15,,opaque
func,PyLongWriter_Create,3.15,,
func,PyLongWriter_Discard,3.15,,
func,PyLongWriter_Finish,3.15,,
func,PyLong_AsDouble,3.2,,
func,PyLong_AsInt,3.13,,
func,PyLong_AsInt32,3.14,,
@@ -409,6 +415,8 @@ func,PyLong_AsUnsignedLongLong,3.2,,
func,PyLong_AsUnsignedLongLongMask,3.2,,
func,PyLong_AsUnsignedLongMask,3.2,,
func,PyLong_AsVoidPtr,3.2,,
func,PyLong_Export,3.15,,
func,PyLong_FreeExport,3.15,,
func,PyLong_FromDouble,3.2,,
func,PyLong_FromInt32,3.14,,
func,PyLong_FromInt64,3.14,,
@@ -425,6 +433,7 @@ func,PyLong_FromUnsignedLongLong,3.2,,
func,PyLong_FromUnsignedNativeBytes,3.14,,
func,PyLong_FromVoidPtr,3.2,,
func,PyLong_GetInfo,3.2,,
func,PyLong_GetNativeLayout,3.15,,
data,PyLong_Type,3.2,,
macro,PyMODEXPORT_FUNC,3.15,,
data,PyMap_Type,3.2,,
-39
View File
@@ -138,45 +138,6 @@ _PyLong_CompactValue(const PyLongObject *op)
#define PyUnstable_Long_CompactValue _PyLong_CompactValue
/* --- Import/Export API -------------------------------------------------- */
typedef struct PyLongLayout {
uint8_t bits_per_digit;
uint8_t digit_size;
int8_t digits_order;
int8_t digit_endianness;
} PyLongLayout;
PyAPI_FUNC(const PyLongLayout*) PyLong_GetNativeLayout(void);
typedef struct PyLongExport {
int64_t value;
uint8_t negative;
Py_ssize_t ndigits;
const void *digits;
// Member used internally, must not be used for other purpose.
Py_uintptr_t _reserved;
} PyLongExport;
PyAPI_FUNC(int) PyLong_Export(
PyObject *obj,
PyLongExport *export_long);
PyAPI_FUNC(void) PyLong_FreeExport(
PyLongExport *export_long);
/* --- PyLongWriter API --------------------------------------------------- */
typedef struct PyLongWriter PyLongWriter;
PyAPI_FUNC(PyLongWriter*) PyLongWriter_Create(
int negative,
Py_ssize_t ndigits,
void **digits);
PyAPI_FUNC(PyObject*) PyLongWriter_Finish(PyLongWriter *writer);
PyAPI_FUNC(void) PyLongWriter_Discard(PyLongWriter *writer);
#ifdef __cplusplus
}
#endif
+38
View File
@@ -166,6 +166,44 @@ PyAPI_FUNC(PyObject *) PyLong_FromString(const char *, char **, int);
PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int);
PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int);
/* --- Import/Export API -------------------------------------------------- */
typedef struct PyLongLayout {
uint8_t bits_per_digit;
uint8_t digit_size;
int8_t digits_order;
int8_t digit_endianness;
} PyLongLayout;
PyAPI_FUNC(const PyLongLayout*) PyLong_GetNativeLayout(void);
typedef struct PyLongExport {
int64_t value;
uint8_t negative;
Py_ssize_t ndigits;
const void *digits;
// Member used internally, must not be used for other purpose.
Py_uintptr_t _reserved;
} PyLongExport;
PyAPI_FUNC(int) PyLong_Export(
PyObject *obj,
PyLongExport *export_long);
PyAPI_FUNC(void) PyLong_FreeExport(
PyLongExport *export_long);
/* --- PyLongWriter API --------------------------------------------------- */
typedef struct PyLongWriter PyLongWriter;
PyAPI_FUNC(PyLongWriter*) PyLongWriter_Create(
int negative,
Py_ssize_t ndigits,
void **digits);
PyAPI_FUNC(PyObject*) PyLongWriter_Finish(PyLongWriter *writer);
PyAPI_FUNC(void) PyLongWriter_Discard(PyLongWriter *writer);
#ifndef Py_LIMITED_API
# define Py_CPYTHON_LONGOBJECT_H
# include "cpython/longobject.h"
+6
View File
@@ -391,6 +391,9 @@ SYMBOL_NAMES = (
"PyList_Sort",
"PyList_Type",
"PyLongRangeIter_Type",
"PyLongWriter_Create",
"PyLongWriter_Discard",
"PyLongWriter_Finish",
"PyLong_AsDouble",
"PyLong_AsInt",
"PyLong_AsInt32",
@@ -409,6 +412,8 @@ SYMBOL_NAMES = (
"PyLong_AsUnsignedLongLongMask",
"PyLong_AsUnsignedLongMask",
"PyLong_AsVoidPtr",
"PyLong_Export",
"PyLong_FreeExport",
"PyLong_FromDouble",
"PyLong_FromInt32",
"PyLong_FromInt64",
@@ -425,6 +430,7 @@ SYMBOL_NAMES = (
"PyLong_FromUnsignedNativeBytes",
"PyLong_FromVoidPtr",
"PyLong_GetInfo",
"PyLong_GetNativeLayout",
"PyLong_Type",
"PyMap_Type",
"PyMapping_Check",
@@ -0,0 +1,5 @@
Added :c:func:`PyLong_GetNativeLayout`, :c:struct:`PyLongLayout`,
:c:struct:`PyLongExport`, :c:func:`PyLong_Export`,
:c:func:`PyLong_FreeExport`, :c:struct:`PyLongWriter`,
:c:func:`PyLongWriter_Create`, :c:func:`PyLongWriter_Finish` and
:c:func:`PyLongWriter_Discard` to the limited API.
+28
View File
@@ -41,6 +41,8 @@
# - 'full-abi': All of the struct is part of the ABI, including the size
# (users may define arrays of these structs).
# Typically used for initialization, rather than at runtime.
# Any members whose names start with an underscore are not part of the
# limited API; they're for CPython's use only.
# - 'opaque': No members are part of the ABI, nor is the size. The Limited
# API only handles these via pointers. The C definition should be
# incomplete (opaque).
@@ -2664,3 +2666,29 @@
[function.Py_SET_SIZE]
# Before 3.15, this was a macro that accessed the PyObject member
added = '3.15'
# PEP 757 import/export API.
[function.PyLong_GetNativeLayout]
added = '3.15'
[function.PyLong_Export]
added = '3.15'
[function.PyLong_FreeExport]
added = '3.15'
[function.PyLongWriter_Create]
added = '3.15'
[function.PyLongWriter_Finish]
added = '3.15'
[function.PyLongWriter_Discard]
added = '3.15'
[struct.PyLongWriter]
added = '3.15'
struct_abi_kind = 'opaque'
[struct.PyLongLayout]
added = '3.15'
struct_abi_kind = 'full-abi'
[struct.PyLongExport]
added = '3.15'
# Note: The `_reserved` member of this struct is for interal use only.
# (The definition of 'full-abi' was clarified when this entry was added.)
struct_abi_kind = 'full-abi'
+6
View File
@@ -366,6 +366,8 @@ EXPORT_FUNC(PyLong_AsUnsignedLongLong)
EXPORT_FUNC(PyLong_AsUnsignedLongLongMask)
EXPORT_FUNC(PyLong_AsUnsignedLongMask)
EXPORT_FUNC(PyLong_AsVoidPtr)
EXPORT_FUNC(PyLong_Export)
EXPORT_FUNC(PyLong_FreeExport)
EXPORT_FUNC(PyLong_FromDouble)
EXPORT_FUNC(PyLong_FromInt32)
EXPORT_FUNC(PyLong_FromInt64)
@@ -382,6 +384,10 @@ EXPORT_FUNC(PyLong_FromUnsignedLongLong)
EXPORT_FUNC(PyLong_FromUnsignedNativeBytes)
EXPORT_FUNC(PyLong_FromVoidPtr)
EXPORT_FUNC(PyLong_GetInfo)
EXPORT_FUNC(PyLong_GetNativeLayout)
EXPORT_FUNC(PyLongWriter_Create)
EXPORT_FUNC(PyLongWriter_Discard)
EXPORT_FUNC(PyLongWriter_Finish)
EXPORT_FUNC(PyMapping_Check)
EXPORT_FUNC(PyMapping_GetItemString)
EXPORT_FUNC(PyMapping_GetOptionalItem)