Skip to content

Commit

Permalink
pythongh-102471: convert decimal module to use PyLong_Export API (PEP…
Browse files Browse the repository at this point in the history
… 757)
  • Loading branch information
skirpichev committed Dec 26, 2024
1 parent d9ed42b commit f7f031f
Showing 1 changed file with 31 additions and 24 deletions.
55 changes: 31 additions & 24 deletions Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -2323,38 +2322,46 @@ 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;
}

uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS;
PyLongExport export_long;

if (_PyLong_IsCompact(l)) {
_dec_settriple(dec, sign, l->long_value.ob_digit[0], 0);
mpd_qfinalize(MPD(dec), ctx, status);
return dec;
if (PyLong_Export(v, &export_long) == -1) {
Py_DECREF(dec);
return NULL;
}
size_t len = _PyLong_DigitCount(l);
if (export_long.digits) {
const PyLongLayout *layout = PyLong_GetNativeLayout();
const uint32_t base = (uint32_t)1 << layout->bits_per_digit;
const uint8_t sign = export_long.negative ? MPD_NEG : MPD_POS;
const Py_ssize_t len = export_long.ndigits;

#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
if (base > UINT16_MAX) {
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 {
const int64_t value = export_long.value;

if (-(int64_t)UINT32_MAX <= value && value <= (int64_t)UINT32_MAX) {
_dec_settriple(dec, value < 0 ? MPD_NEG : MPD_POS,
(uint32_t)Py_ABS(value), 0);
mpd_qfinalize(MPD(dec), ctx, status);
}
else {
mpd_qset_i64(MPD(dec), value, ctx, status);
}
}
return dec;
}

Expand Down

0 comments on commit f7f031f

Please sign in to comment.