diff --git a/dtool/src/interrogatedb/py_compat.h b/dtool/src/interrogatedb/py_compat.h index c5474b21ee..20946e7f48 100644 --- a/dtool/src/interrogatedb/py_compat.h +++ b/dtool/src/interrogatedb/py_compat.h @@ -243,6 +243,18 @@ INLINE PyObject *PyObject_CallMethodOneArg(PyObject *obj, PyObject *name, PyObje } #endif +/* Python 3.12 */ + +#if PY_VERSION_HEX < 0x030C0000 +# define PyLong_IsNonNegative(value) (Py_SIZE((value)) >= 0) +#else +INLINE bool PyLong_IsNonNegative(PyObject *value) { + int overflow = 0; + long longval = PyLong_AsLongAndOverflow(value, &overflow); + return overflow == 1 || longval >= 0; +} +#endif + /* Other Python implementations */ // _PyErr_OCCURRED is an undocumented macro version of PyErr_Occurred. diff --git a/panda/src/putil/bitArray_ext.cxx b/panda/src/putil/bitArray_ext.cxx index 215d920cb4..6e0d860238 100644 --- a/panda/src/putil/bitArray_ext.cxx +++ b/panda/src/putil/bitArray_ext.cxx @@ -32,7 +32,7 @@ __init__(PyObject *init_value) { } #endif - if (!PyLong_Check(init_value) || Py_SIZE(init_value) < 0) { + if (!PyLong_Check(init_value) || !PyLong_IsNonNegative(init_value)) { PyErr_SetString(PyExc_ValueError, "BitArray constructor requires a positive integer"); return; } @@ -88,7 +88,7 @@ __getstate__() const { */ void Extension:: __setstate__(PyObject *state) { - if (Py_SIZE(state) >= 0) { + if (PyLong_IsNonNegative(state)) { __init__(state); } else { PyObject *inverted = PyNumber_Invert(state); diff --git a/panda/src/putil/doubleBitMask_ext.I b/panda/src/putil/doubleBitMask_ext.I index b774f22096..748def0371 100644 --- a/panda/src/putil/doubleBitMask_ext.I +++ b/panda/src/putil/doubleBitMask_ext.I @@ -28,8 +28,7 @@ __init__(PyObject *init_value) { return; } #endif - - if (!PyLong_Check(init_value) || Py_SIZE(init_value) < 0) { + if (!PyLong_Check(init_value) || !PyLong_IsNonNegative(init_value)) { PyErr_SetString(PyExc_ValueError, "DoubleBitMask constructor requires a positive integer"); return; } diff --git a/tests/putil/test_bitarray.py b/tests/putil/test_bitarray.py index 5da2fdc725..293be8df74 100644 --- a/tests/putil/test_bitarray.py +++ b/tests/putil/test_bitarray.py @@ -32,6 +32,9 @@ def test_bitarray_pickle(): ba = BitArray(123) assert ba == pickle.loads(pickle.dumps(ba, -1)) + ba = BitArray(1 << 128) + assert ba == pickle.loads(pickle.dumps(ba, -1)) + def test_bitarray_has_any_of(): ba = BitArray()