Skip to content

Commit b4c7d46

Browse files
committed
Fix PyLong digits access in CPython 3.12.
Needed after python/cpython#101292 See cython#5238
1 parent 1dba3d3 commit b4c7d46

File tree

4 files changed

+18
-10
lines changed

4 files changed

+18
-10
lines changed

Cython/Utility/Builtins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static PyObject *__Pyx_PyLong_AbsNeg(PyObject *num);/*proto*/
247247
static PyObject *__Pyx_PyLong_AbsNeg(PyObject *n) {
248248
if (likely(Py_SIZE(n) == -1)) {
249249
// digits are unsigned
250-
return PyLong_FromLong(((PyLongObject*)n)->ob_digit[0]);
250+
return PyLong_FromLong(__Pyx_PyLong_Digits(n)[0]);
251251
}
252252
#if CYTHON_COMPILING_IN_CPYTHON
253253
{

Cython/Utility/Optimize.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ static PyObject* __Pyx__PyNumber_PowerOf2(PyObject *two, PyObject *exp, PyObject
977977
const Py_ssize_t size = Py_SIZE(exp);
978978
// tuned to optimise branch prediction
979979
if (likely(size == 1)) {
980-
shiftby = ((PyLongObject*)exp)->ob_digit[0];
980+
shiftby = __Pyx_PyLong_Digits(exp)[0];
981981
} else if (size == 0) {
982982
return PyInt_FromLong(1L);
983983
} else if (unlikely(size < 0)) {
@@ -1058,7 +1058,7 @@ static CYTHON_INLINE {{c_ret_type}} __Pyx_PyInt_{{'' if ret_type.is_pyobject els
10581058
int unequal;
10591059
unsigned long uintval;
10601060
Py_ssize_t size = Py_SIZE({{pyval}});
1061-
const digit* digits = ((PyLongObject*){{pyval}})->ob_digit;
1061+
const digit* digits = __Pyx_PyLong_Digits({{pyval}});
10621062
if (intval == 0) {
10631063
// == 0 => Py_SIZE(pyval) == 0
10641064
{{return_compare('size', '0', c_op)}}
@@ -1237,7 +1237,7 @@ static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, long intval,
12371237
PY_LONG_LONG ll{{ival}}, llx;
12381238
#endif
12391239
{{endif}}
1240-
const digit* digits = ((PyLongObject*){{pyval}})->ob_digit;
1240+
const digit* digits = __Pyx_PyLong_Digits({{pyval}});
12411241
const Py_ssize_t size = Py_SIZE({{pyval}});
12421242
{{if c_op == '&'}}
12431243
// special case for &-ing arbitrarily large numbers with known single digit operands
@@ -1492,7 +1492,7 @@ static {{c_ret_type}} {{cfunc_name}}(PyObject *op1, PyObject *op2, double floatv
14921492

14931493
if (likely(PyLong_CheckExact({{pyval}}))) {
14941494
#if CYTHON_USE_PYLONG_INTERNALS
1495-
const digit* digits = ((PyLongObject*){{pyval}})->ob_digit;
1495+
const digit* digits = __Pyx_PyLong_Digits({{pyval}});
14961496
const Py_ssize_t size = Py_SIZE({{pyval}});
14971497
switch (size) {
14981498
case 0: {{fval}} = 0.0; {{zerodiv_check(fval)}} break;

Cython/Utility/StringTools.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyO
10651065
if (Py_SIZE(value) == 0) {
10661066
ival = 0;
10671067
} else {
1068-
ival = ((PyLongObject*)value)->ob_digit[0];
1068+
ival = __Pyx_PyLong_Digits(value)[0];
10691069
if (unlikely(ival > 255)) goto bad_range;
10701070
}
10711071
} else

Cython/Utility/TypeConversion.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*);
129129
// __Pyx_PyNumber_Float is now in it's own section since it has dependencies (needed to make
130130
// string conversion work the same in all circumstances)
131131

132+
#if CYTHON_USE_PYLONG_INTERNALS
133+
#if PY_VERSION_HEX >= 0x030C00A5
134+
#define __Pyx_PyLong_Digits(x) (((PyLongObject*)b)->long_value.ob_digit)
135+
#else
136+
#define __Pyx_PyLong_Digits(x) (((PyLongObject*)b)->ob_digit)
137+
#endif
138+
#endif
139+
132140
#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
133141
static int __Pyx_sys_getdefaultencoding_not_ascii;
134142
static int __Pyx_init_sys_getdefaultencoding_params(void) {
@@ -405,7 +413,7 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
405413
#endif
406414
if (likely(PyLong_CheckExact(b))) {
407415
#if CYTHON_USE_PYLONG_INTERNALS
408-
const digit* digits = ((PyLongObject*)b)->ob_digit;
416+
const digit* digits = __Pyx_PyLong_Digits(b);
409417
const Py_ssize_t size = Py_SIZE(b);
410418
// handle most common case first to avoid indirect branch and optimise branch prediction
411419
if (likely(__Pyx_sst_abs(size) <= 1)) {
@@ -478,7 +486,7 @@ static CYTHON_INLINE PyObject* __Pyx__PyNumber_Float(PyObject* obj) {
478486
double val;
479487
if (PyLong_CheckExact(obj)) {
480488
#if CYTHON_USE_PYLONG_INTERNALS
481-
const digit* digits = ((PyLongObject*)obj)->ob_digit;
489+
const digit* digits = __Pyx_PyLong_Digits(obj);
482490
switch (Py_SIZE(obj)) {
483491
case 0:
484492
val = 0.0;
@@ -968,7 +976,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
968976
if (likely(PyLong_Check(x))) {
969977
if (is_unsigned) {
970978
#if CYTHON_USE_PYLONG_INTERNALS
971-
const digit* digits = ((PyLongObject*)x)->ob_digit;
979+
const digit* digits = __Pyx_PyLong_Digits(x);
972980
switch (Py_SIZE(x)) {
973981
case 0: return ({{TYPE}}) 0;
974982
case 1: __PYX_VERIFY_RETURN_INT({{TYPE}}, digit, digits[0])
@@ -1009,7 +1017,7 @@ static CYTHON_INLINE {{TYPE}} {{FROM_PY_FUNCTION}}(PyObject *x) {
10091017
} else {
10101018
// signed
10111019
#if CYTHON_USE_PYLONG_INTERNALS
1012-
const digit* digits = ((PyLongObject*)x)->ob_digit;
1020+
const digit* digits = __Pyx_PyLong_Digits(x);
10131021
switch (Py_SIZE(x)) {
10141022
case 0: return ({{TYPE}}) 0;
10151023
case -1: __PYX_VERIFY_RETURN_INT({{TYPE}}, sdigit, (sdigit) (-(sdigit)digits[0]))

0 commit comments

Comments
 (0)