Skip to content

Commit 879d287

Browse files
authored
gh-102471: convert decimal module to use PyLong_Export API (PEP 757) (#128267)
1 parent aef52ca commit 879d287

File tree

1 file changed

+27
-24
lines changed

1 file changed

+27
-24
lines changed

Modules/_decimal/_decimal.c

+27-24
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#endif
3131

3232
#include <Python.h>
33-
#include "pycore_long.h" // _PyLong_IsZero()
3433
#include "pycore_pystate.h" // _PyThreadState_GET()
3534
#include "pycore_typeobject.h"
3635
#include "complexobject.h"
@@ -2323,38 +2322,42 @@ static PyObject *
23232322
dec_from_long(decimal_state *state, PyTypeObject *type, PyObject *v,
23242323
const mpd_context_t *ctx, uint32_t *status)
23252324
{
2326-
PyObject *dec;
2327-
PyLongObject *l = (PyLongObject *)v;
2325+
PyObject *dec = PyDecType_New(state, type);
23282326

2329-
dec = PyDecType_New(state, type);
23302327
if (dec == NULL) {
23312328
return NULL;
23322329
}
23332330

2334-
if (_PyLong_IsZero(l)) {
2335-
_dec_settriple(dec, MPD_POS, 0, 0);
2336-
return dec;
2337-
}
2338-
2339-
uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS;
2331+
PyLongExport export_long;
23402332

2341-
if (_PyLong_IsCompact(l)) {
2342-
_dec_settriple(dec, sign, l->long_value.ob_digit[0], 0);
2343-
mpd_qfinalize(MPD(dec), ctx, status);
2344-
return dec;
2333+
if (PyLong_Export(v, &export_long) == -1) {
2334+
Py_DECREF(dec);
2335+
return NULL;
23452336
}
2346-
size_t len = _PyLong_DigitCount(l);
2337+
if (export_long.digits) {
2338+
const PyLongLayout *layout = PyLong_GetNativeLayout();
2339+
uint32_t base = (uint32_t)1 << layout->bits_per_digit;
2340+
uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
2341+
Py_ssize_t len = export_long.ndigits;
23472342

2348-
#if PYLONG_BITS_IN_DIGIT == 30
2349-
mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
2350-
ctx, status);
2351-
#elif PYLONG_BITS_IN_DIGIT == 15
2352-
mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE,
2353-
ctx, status);
2354-
#else
2355-
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
2356-
#endif
2343+
assert(layout->bits_per_digit <= 32);
2344+
assert(layout->digits_order == -1);
2345+
assert(layout->digit_endianness == (PY_LITTLE_ENDIAN ? -1 : 1));
2346+
assert(layout->digit_size == 2 || layout->digit_size == 4);
23572347

2348+
if (layout->digit_size == 4) {
2349+
mpd_qimport_u32(MPD(dec), export_long.digits, len, sign,
2350+
base, ctx, status);
2351+
}
2352+
else {
2353+
mpd_qimport_u16(MPD(dec), export_long.digits, len, sign,
2354+
base, ctx, status);
2355+
}
2356+
PyLong_FreeExport(&export_long);
2357+
}
2358+
else {
2359+
mpd_qset_i64(MPD(dec), export_long.value, ctx, status);
2360+
}
23582361
return dec;
23592362
}
23602363

0 commit comments

Comments
 (0)