Skip to content

Commit ab9258d

Browse files
authored
PEP 757: misc edits (#3984)
1 parent c5010ea commit ab9258d

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

peps/pep-0757.rst

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ Export API
129129
130130
Read-only array of unsigned digits. Can be ``NULL``.
131131
132+
If :c:member:`digits` not ``NULL``, a private field of the
133+
:c:struct:`PyLongExport` structure stores a strong reference to the Python
134+
:class:`int` object to make sure that that structure remains valid until
135+
:c:func:`PyLong_FreeExport()` is called.
136+
132137
133138
.. c:function:: int PyLong_Export(PyObject *obj, PyLongExport *export_long)
134139
@@ -146,11 +151,6 @@ Export API
146151
On CPython 3.14, no memory copy is needed, it's just a thin wrapper to
147152
expose Python int internal digits array.
148153
149-
If :c:member:`~PyLongExport.digits` not ``NULL``, a private field of
150-
the :c:struct:`PyLongExport` structure stores a strong reference to
151-
the Python :class:`int` object to make sure that that structure
152-
remains valid until :c:func:`PyLong_FreeExport()` is called.
153-
154154
155155
.. c:function:: void PyLong_FreeExport(PyLongExport *export_long)
156156
@@ -183,9 +183,9 @@ create a Python :class:`int` object from a digits array.
183183
greater than or equal to 0.
184184
185185
The caller must initialize the array of digits *digits* and then call
186-
:c:func:`PyLongWriter_Finish` to get a Python :class:`int`. Digits must be
187-
in the range [``0``; ``PyLong_BASE - 1``]. Unused digits must be set to
188-
``0``.
186+
:c:func:`PyLongWriter_Finish` to get a Python :class:`int`. Digits must be
187+
in the range [``0``; ``(1 << sys.int_info.bits_per_digit) - 1``]. Unused digits must
188+
be set to ``0``.
189189
190190
On CPython 3.14, the implementation is a thin wrapper to the private
191191
:c:func:`!_PyLong_New()` function.
@@ -238,6 +238,18 @@ Implementation
238238
Benchmarks
239239
==========
240240
241+
Code::
242+
243+
/* Query parameters of Python’s internal representation of integers. */
244+
const PyLongLayout *layout = PyLong_GetNativeLayout();
245+
246+
size_t int_digit_size = layout->digit_size;
247+
int int_digits_order = layout->digits_order;
248+
size_t int_bits_per_digit = layout->bits_per_digit;
249+
size_t int_nails = int_digit_size*8 - int_bits_per_digit;
250+
int int_endianness = layout->endianness;
251+
252+
241253
Export: :c:func:`PyLong_Export()` with gmpy2
242254
--------------------------------------------
243255
@@ -246,28 +258,26 @@ Code::
246258
static void
247259
mpz_set_PyLong(mpz_t z, PyObject *obj)
248260
{
249-
const PyLongLayout* layout = PyLong_GetNativeLayout();
250261
static PyLongExport long_export;
251262
252263
PyLong_Export(obj, &long_export);
253264
if (long_export.digits) {
254-
mpz_import(z, long_export.ndigits, layout->digits_order,
255-
layout->digit_size, layout->endianness,
256-
layout->digit_size*8 - layout->bits_per_digit,
257-
long_export.digits);
265+
mpz_import(z, long_export.ndigits, int_digits_order, int_digit_size,
266+
int_endianness, int_nails, long_export.digits);
258267
if (long_export.negative) {
259268
mpz_neg(z, z);
260269
}
261270
PyLong_FreeExport(&long_export);
262271
}
263272
else {
264-
if (LONG_MIN <= long_export.value && long_export.value <= LONG_MAX) {
265-
mpz_set_si(z, long_export.value);
273+
const int64_t value = long_export.value;
274+
275+
if (LONG_MIN <= value && value <= LONG_MAX) {
276+
mpz_set_si(z, value);
266277
}
267278
else {
268-
mpz_import(z, 1, -1, sizeof(int64_t), 0, 0,
269-
&long_export.value);
270-
if (long_export.value < 0) {
279+
mpz_import(z, 1, -1, sizeof(int64_t), 0, 0, &value);
280+
if (value < 0) {
271281
mpz_t tmp;
272282
mpz_init(tmp);
273283
mpz_ui_pow_ui(tmp, 2, 64);
@@ -324,20 +334,17 @@ Code::
324334
return PyLong_FromLong(mpz_get_si(obj->z));
325335
}
326336
327-
const PyLongLayout *layout = PyLong_GetNativeLayout();
328337
size_t size = (mpz_sizeinbase(obj->z, 2) +
329-
layout->bits_per_digit - 1) / layout->bits_per_digit;
338+
int_bits_per_digit - 1) / int_bits_per_digit;
330339
void *digits;
331340
PyLongWriter *writer = PyLongWriter_Create(mpz_sgn(obj->z) < 0, size,
332341
&digits);
333342
if (writer == NULL) {
334343
return NULL;
335344
}
336345
337-
mpz_export(digits, NULL, layout->endianness,
338-
layout->digit_size, layout->digits_order,
339-
layout->digit_size*8 - layout->bits_per_digit,
340-
obj->z);
346+
mpz_export(digits, NULL, int_digits_order, int_digit_size,
347+
int_endianness, int_nails, obj->z);
341348
342349
return PyLongWriter_Finish(writer);
343350
}
@@ -389,11 +396,11 @@ Open Questions
389396
:c:func:`PyLong_GetNativeLayout()` function returns a C structure
390397
which is more convenient to use in C than :data:`sys.int_info` which uses
391398
Python objects.
392-
* Currenly, all required information for :class:`int` import/export is
399+
* Currently, all required information for :class:`int` import/export is
393400
already available via :c:func:`PyLong_GetInfo()` or :data:`sys.int_info`.
394401
Native endianness of "digits" and current order of digits (least
395402
significant digit first) --- is a common denominator of all libraries
396-
for aribitrary precision integer arithmetic. So, shouldn't we just remove
403+
for arbitrary precision integer arithmetic. So, shouldn't we just remove
397404
from API both :c:struct:`PyLongLayout` and :c:func:`PyLong_GetNativeLayout()` (which
398405
is actually just a minor convenience)?
399406

0 commit comments

Comments
 (0)