gh-102471: convert decimal module to use PyLong_Export API (PEP 757) (#128267)

This commit is contained in:
Sergey B Kirpichev 2025-01-06 13:29:18 +03:00 committed by GitHub
parent aef52ca8b3
commit 879d287f49
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -30,7 +30,6 @@
#endif
#include <Python.h>
#include "pycore_long.h" // _PyLong_IsZero()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_typeobject.h"
#include "complexobject.h"
@ -2323,38 +2322,42 @@ static PyObject *
dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v,
const mpd_context_t *ctx, uint32_t *status)
{
PyObject *dec;
PyLongObject *l = (PyLongObject *)v;
PyObject *dec = PyDecType_New(state, type);
dec = PyDecType_New(state, type);
if (dec == NULL) {
return NULL;
}
if (_PyLong_IsZero(l)) {
_dec_settriple(dec, MPD_POS, 0, 0);
return dec;
PyLongExport export_long;
if (PyLong_Export(v, &export_long) == -1) {
Py_DECREF(dec);
return NULL;
}
if (export_long.digits) {
const PyLongLayout *layout = PyLong_GetNativeLayout();
uint32_t base = (uint32_t)1 << layout->bits_per_digit;
uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
Py_ssize_t len = export_long.ndigits;
uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS;
assert(layout->bits_per_digit <= 32);
assert(layout->digits_order == -1);
assert(layout->digit_endianness == (PY_LITTLE_ENDIAN ? -1 : 1));
assert(layout->digit_size == 2 || layout->digit_size == 4);
if (_PyLong_IsCompact(l)) {
_dec_settriple(dec, sign, l->long_value.ob_digit[0], 0);
mpd_qfinalize(MPD(dec), ctx, status);
return dec;
if (layout->digit_size == 4) {
mpd_qimport_u32(MPD(dec), export_long.digits, len, sign,
base, ctx, status);
}
else {
mpd_qimport_u16(MPD(dec), export_long.digits, len, sign,
base, ctx, status);
}
PyLong_FreeExport(&export_long);
}
else {
mpd_qset_i64(MPD(dec), export_long.value, ctx, status);
}
size_t len = _PyLong_DigitCount(l);
#if PYLONG_BITS_IN_DIGIT == 30
mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
ctx, status);
#elif PYLONG_BITS_IN_DIGIT == 15
mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
ctx, status);
#else
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
#endif
return dec;
}