Skip to content

Commit

Permalink
Replace deprecated _PyLong_new with PyLongWriter API (#18532)
Browse files Browse the repository at this point in the history
`_PyLong_New` will be deprecated in `3.14.0a5`. Replace it with the
`PyLongWriter` API available in `pythoncapi_compat.h` for older
versions.

https://docs.python.org/dev/c-api/long.html#pylongwriter-api
  • Loading branch information
cdce8p authored Jan 27, 2025
1 parent ae56892 commit 42b5999
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 27 deletions.
24 changes: 8 additions & 16 deletions mypyc/lib-rt/int_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,6 @@ PyObject *CPyBool_Str(bool b) {
return PyObject_Str(b ? Py_True : Py_False);
}

static void CPyLong_NormalizeUnsigned(PyLongObject *v) {
Py_ssize_t i = CPY_LONG_SIZE_UNSIGNED(v);
while (i > 0 && CPY_LONG_DIGIT(v, i - 1) == 0)
i--;
CPyLong_SetUnsignedSize(v, i);
}

// Bitwise op '&', '|' or '^' using the generic (slow) API
static CPyTagged GenericBitwiseOp(CPyTagged a, CPyTagged b, char op) {
PyObject *aobj = CPyTagged_AsObject(a);
Expand Down Expand Up @@ -302,7 +295,6 @@ CPyTagged CPyTagged_BitwiseLongOp_(CPyTagged a, CPyTagged b, char op) {
digit *adigits = GetIntDigits(a, &asize, abuf);
digit *bdigits = GetIntDigits(b, &bsize, bbuf);

PyLongObject *r;
if (unlikely(asize < 0 || bsize < 0)) {
// Negative operand. This is slower, but bitwise ops on them are pretty rare.
return GenericBitwiseOp(a, b, op);
Expand All @@ -317,31 +309,31 @@ CPyTagged CPyTagged_BitwiseLongOp_(CPyTagged a, CPyTagged b, char op) {
asize = bsize;
bsize = tmp_size;
}
r = _PyLong_New(op == '&' ? asize : bsize);
if (unlikely(r == NULL)) {
void *digits = NULL;
PyLongWriter *writer = PyLongWriter_Create(0, op == '&' ? asize : bsize, &digits);
if (unlikely(writer == NULL)) {
CPyError_OutOfMemory();
}
Py_ssize_t i;
if (op == '&') {
for (i = 0; i < asize; i++) {
CPY_LONG_DIGIT(r, i) = adigits[i] & bdigits[i];
((digit *)digits)[i] = adigits[i] & bdigits[i];
}
} else {
if (op == '|') {
for (i = 0; i < asize; i++) {
CPY_LONG_DIGIT(r, i) = adigits[i] | bdigits[i];
((digit *)digits)[i] = adigits[i] | bdigits[i];
}
} else {
for (i = 0; i < asize; i++) {
CPY_LONG_DIGIT(r, i) = adigits[i] ^ bdigits[i];
((digit *)digits)[i] = adigits[i] ^ bdigits[i];
}
}
for (; i < bsize; i++) {
CPY_LONG_DIGIT(r, i) = bdigits[i];
((digit *)digits)[i] = bdigits[i];
}
}
CPyLong_NormalizeUnsigned(r);
return CPyTagged_StealFromObject((PyObject *)r);
return CPyTagged_StealFromObject(PyLongWriter_Finish(writer));
}

// Bitwise '~' slow path
Expand Down
11 changes: 0 additions & 11 deletions mypyc/lib-rt/mypyc_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,13 @@ static inline CPyTagged CPyTagged_ShortFromSsize_t(Py_ssize_t x) {
// Number of digits, assuming int is non-negative
#define CPY_LONG_SIZE_UNSIGNED(o) CPY_LONG_SIZE(o)

static inline void CPyLong_SetUnsignedSize(PyLongObject *o, Py_ssize_t n) {
if (n == 0)
o->long_value.lv_tag = CPY_SIGN_ZERO;
else
o->long_value.lv_tag = n << CPY_NON_SIZE_BITS;
}

#else

#define CPY_LONG_DIGIT(o, n) ((o)->ob_digit[n])
#define CPY_LONG_IS_NEGATIVE(o) (((o)->ob_base.ob_size < 0)
#define CPY_LONG_SIZE_SIGNED(o) ((o)->ob_base.ob_size)
#define CPY_LONG_SIZE_UNSIGNED(o) ((o)->ob_base.ob_size)

static inline void CPyLong_SetUnsignedSize(PyLongObject *o, Py_ssize_t n) {
o->ob_base.ob_size = n;
}

#endif

// Are we targeting Python 3.13 or newer?
Expand Down

0 comments on commit 42b5999

Please sign in to comment.