diff --git a/peps/pep-0757.rst b/peps/pep-0757.rst index fd315a8db8d..1bd675b8b1a 100644 --- a/peps/pep-0757.rst +++ b/peps/pep-0757.rst @@ -110,9 +110,9 @@ Export a Python integer as a digits array:: On CPython 3.14, no memory copy is needed, it's just a thin wrapper to expose Python int internal digits array. -``PyLong_DigitArray._reserved`` stores a strong reference to the Python -:class:`int` object to make sure that that structure remains valid until -``PyLong_FreeExport()`` is called. +``PyLong_DigitArray._reserved``, if ``digits`` not ``NULL``, stores a strong +reference to the Python :class:`int` object to make sure that that structure +remains valid until ``PyLong_FreeExport()`` is called. PyLong_Export() @@ -136,8 +136,8 @@ Python :class:`int` object or a subclass. ``PyLong_FreeExport()`` must be called once done with using *array*. -PyLong_FreeDigitArray() -^^^^^^^^^^^^^^^^^^^^^^^ +PyLong_FreeExport() +^^^^^^^^^^^^^^^^^^^ API:: @@ -256,35 +256,35 @@ Code:: static void mpz_set_PyLong(mpz_t z, PyObject *obj) { - int overflow; - long val = PyLong_AsLongAndOverflow(obj, &overflow); - - if (overflow) { - const PyLongLayout* layout = PyLong_GetNativeLayout(); - static PyLong_DigitArray long_export; - - PyLong_Export(obj, &long_export); - if (long_export.digits) { - mpz_import(z, long_export.ndigits, layout->digits_order, - layout->digit_size, layout->endian, - layout->digit_size*8 - layout->bits_per_digit, - long_export.digits); - } - else { - if (long_export.negative) { - long_export.value = -long_export.value; - } - mpz_import(z, 1, -1, sizeof(int64_t), 0, 0, - &long_export.value); - } - PyLong_FreeExport(&long_export); - + const PyLongLayout* layout = PyLong_GetNativeLayout(); + static PyLong_DigitArray long_export; + + PyLong_Export(obj, &long_export); + if (long_export.digits) { + mpz_import(z, long_export.ndigits, layout->digits_order, + layout->digit_size, layout->endian, + layout->digit_size*8 - layout->bits_per_digit, + long_export.digits); if (long_export.negative) { mpz_neg(z, z); } + PyLong_FreeExport(&long_export); } else { - mpz_set_si(z, val); + if (LONG_MIN <= long_export.value <= LONG_MAX) { + mpz_set_si(z, long_export.value); + } + else { + mpz_import(z, 1, -1, sizeof(int64_t), 0, 0, + &long_export.value); + if (long_export.value < 0) { + mpz_t tmp; + mpz_init(tmp); + mpz_ui_pow_ui(tmp, 2, 8*sizeof(size_t)); + mpz_sub(z, z, tmp); + mpz_clear(tmp); + } + } } }