Skip to content

Commit 09b624b

Browse files
authored
gh-132639: Adds PyLong_AsNativeBytes, PyLong_FromNativeBytes and PyLong_FromUnsignedNativeBytes to the limited API (GH-132640)
1 parent 70b322d commit 09b624b

File tree

7 files changed

+83
-51
lines changed

7 files changed

+83
-51
lines changed

Doc/data/stable_abi.dat

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/cpython/longobject.h

-51
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,6 @@
77

88
PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
99

10-
#define Py_ASNATIVEBYTES_DEFAULTS -1
11-
#define Py_ASNATIVEBYTES_BIG_ENDIAN 0
12-
#define Py_ASNATIVEBYTES_LITTLE_ENDIAN 1
13-
#define Py_ASNATIVEBYTES_NATIVE_ENDIAN 3
14-
#define Py_ASNATIVEBYTES_UNSIGNED_BUFFER 4
15-
#define Py_ASNATIVEBYTES_REJECT_NEGATIVE 8
16-
#define Py_ASNATIVEBYTES_ALLOW_INDEX 16
17-
18-
/* PyLong_AsNativeBytes: Copy the integer value to a native variable.
19-
buffer points to the first byte of the variable.
20-
n_bytes is the number of bytes available in the buffer. Pass 0 to request
21-
the required size for the value.
22-
flags is a bitfield of the following flags:
23-
* 1 - little endian
24-
* 2 - native endian
25-
* 4 - unsigned destination (e.g. don't reject copying 255 into one byte)
26-
* 8 - raise an exception for negative inputs
27-
* 16 - call __index__ on non-int types
28-
If flags is -1 (all bits set), native endian is used, value truncation
29-
behaves most like C (allows negative inputs and allow MSB set), and non-int
30-
objects will raise a TypeError.
31-
Big endian mode will write the most significant byte into the address
32-
directly referenced by buffer; little endian will write the least significant
33-
byte into that address.
34-
35-
If an exception is raised, returns a negative value.
36-
Otherwise, returns the number of bytes that are required to store the value.
37-
To check that the full value is represented, ensure that the return value is
38-
equal or less than n_bytes.
39-
All n_bytes are guaranteed to be written (unless an exception occurs), and
40-
so ignoring a positive return value is the equivalent of a downcast in C.
41-
In cases where the full value could not be represented, the returned value
42-
may be larger than necessary - this function is not an accurate way to
43-
calculate the bit length of an integer object.
44-
*/
45-
PyAPI_FUNC(Py_ssize_t) PyLong_AsNativeBytes(PyObject* v, void* buffer,
46-
Py_ssize_t n_bytes, int flags);
47-
48-
/* PyLong_FromNativeBytes: Create an int value from a native integer
49-
n_bytes is the number of bytes to read from the buffer. Passing 0 will
50-
always produce the zero int.
51-
PyLong_FromUnsignedNativeBytes always produces a non-negative int.
52-
flags is the same as for PyLong_AsNativeBytes, but only supports selecting
53-
the endianness or forcing an unsigned buffer.
54-
55-
Returns the int object, or NULL with an exception set. */
56-
PyAPI_FUNC(PyObject*) PyLong_FromNativeBytes(const void* buffer, size_t n_bytes,
57-
int flags);
58-
PyAPI_FUNC(PyObject*) PyLong_FromUnsignedNativeBytes(const void* buffer,
59-
size_t n_bytes, int flags);
60-
6110
PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op);
6211
PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op);
6312

Include/longobject.h

+52
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,58 @@ PyAPI_FUNC(int) PyLong_AsInt32(PyObject *obj, int32_t *value);
4040
PyAPI_FUNC(int) PyLong_AsUInt32(PyObject *obj, uint32_t *value);
4141
PyAPI_FUNC(int) PyLong_AsInt64(PyObject *obj, int64_t *value);
4242
PyAPI_FUNC(int) PyLong_AsUInt64(PyObject *obj, uint64_t *value);
43+
44+
#define Py_ASNATIVEBYTES_DEFAULTS -1
45+
#define Py_ASNATIVEBYTES_BIG_ENDIAN 0
46+
#define Py_ASNATIVEBYTES_LITTLE_ENDIAN 1
47+
#define Py_ASNATIVEBYTES_NATIVE_ENDIAN 3
48+
#define Py_ASNATIVEBYTES_UNSIGNED_BUFFER 4
49+
#define Py_ASNATIVEBYTES_REJECT_NEGATIVE 8
50+
#define Py_ASNATIVEBYTES_ALLOW_INDEX 16
51+
52+
/* PyLong_AsNativeBytes: Copy the integer value to a native variable.
53+
buffer points to the first byte of the variable.
54+
n_bytes is the number of bytes available in the buffer. Pass 0 to request
55+
the required size for the value.
56+
flags is a bitfield of the following flags:
57+
* 1 - little endian
58+
* 2 - native endian
59+
* 4 - unsigned destination (e.g. don't reject copying 255 into one byte)
60+
* 8 - raise an exception for negative inputs
61+
* 16 - call __index__ on non-int types
62+
If flags is -1 (all bits set), native endian is used, value truncation
63+
behaves most like C (allows negative inputs and allow MSB set), and non-int
64+
objects will raise a TypeError.
65+
Big endian mode will write the most significant byte into the address
66+
directly referenced by buffer; little endian will write the least significant
67+
byte into that address.
68+
69+
If an exception is raised, returns a negative value.
70+
Otherwise, returns the number of bytes that are required to store the value.
71+
To check that the full value is represented, ensure that the return value is
72+
equal or less than n_bytes.
73+
All n_bytes are guaranteed to be written (unless an exception occurs), and
74+
so ignoring a positive return value is the equivalent of a downcast in C.
75+
In cases where the full value could not be represented, the returned value
76+
may be larger than necessary - this function is not an accurate way to
77+
calculate the bit length of an integer object.
78+
*/
79+
PyAPI_FUNC(Py_ssize_t) PyLong_AsNativeBytes(PyObject* v, void* buffer,
80+
Py_ssize_t n_bytes, int flags);
81+
82+
/* PyLong_FromNativeBytes: Create an int value from a native integer
83+
n_bytes is the number of bytes to read from the buffer. Passing 0 will
84+
always produce the zero int.
85+
PyLong_FromUnsignedNativeBytes always produces a non-negative int.
86+
flags is the same as for PyLong_AsNativeBytes, but only supports selecting
87+
the endianness or forcing an unsigned buffer.
88+
89+
Returns the int object, or NULL with an exception set. */
90+
PyAPI_FUNC(PyObject*) PyLong_FromNativeBytes(const void* buffer, size_t n_bytes,
91+
int flags);
92+
PyAPI_FUNC(PyObject*) PyLong_FromUnsignedNativeBytes(const void* buffer,
93+
size_t n_bytes, int flags);
94+
4395
#endif
4496

4597
PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);

Lib/test/test_stable_abi_ctypes.py

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Added :c:func:`PyLong_AsNativeBytes`, :c:func:`PyLong_FromNativeBytes` and
2+
:c:func:`PyLong_FromUnsignedNativeBytes` to the limited C API.

Misc/stable_abi.toml

+20
Original file line numberDiff line numberDiff line change
@@ -2528,6 +2528,26 @@
25282528
added = '3.14'
25292529
[function.PyLong_AsUInt64]
25302530
added = '3.14'
2531+
[function.PyLong_AsNativeBytes]
2532+
added = '3.14'
2533+
[function.PyLong_FromNativeBytes]
2534+
added = '3.14'
2535+
[function.PyLong_FromUnsignedNativeBytes]
2536+
added = '3.14'
2537+
[const.Py_ASNATIVEBYTES_DEFAULTS]
2538+
added = '3.14'
2539+
[const.Py_ASNATIVEBYTES_BIG_ENDIAN]
2540+
added = '3.14'
2541+
[const.Py_ASNATIVEBYTES_LITTLE_ENDIAN]
2542+
added = '3.14'
2543+
[const.Py_ASNATIVEBYTES_NATIVE_ENDIAN]
2544+
added = '3.14'
2545+
[const.Py_ASNATIVEBYTES_UNSIGNED_BUFFER]
2546+
added = '3.14'
2547+
[const.Py_ASNATIVEBYTES_REJECT_NEGATIVE]
2548+
added = '3.14'
2549+
[const.Py_ASNATIVEBYTES_ALLOW_INDEX]
2550+
added = '3.14'
25312551
[const.Py_tp_vectorcall]
25322552
added = '3.14'
25332553
[function.PyType_GetBaseByToken]

PC/python3dll.c

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)