diff --git a/_multibuild b/_multibuild index cd365a1..1530886 100644 --- a/_multibuild +++ b/_multibuild @@ -1,5 +1,4 @@ - test-py310 test-py311 test-py312 test-py313 diff --git a/numba-0.60.0.tar.gz b/numba-0.60.0.tar.gz deleted file mode 100644 index 26d56b2..0000000 --- a/numba-0.60.0.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16 -size 2702171 diff --git a/numba-0.61.0.tar.gz b/numba-0.61.0.tar.gz new file mode 100644 index 0000000..2cada8e --- /dev/null +++ b/numba-0.61.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:888d2e89b8160899e19591467e8fdd4970e07606e1fbc248f239c89818d5f925 +size 2816484 diff --git a/numpy21.patch b/numpy21.patch deleted file mode 100644 index 398a1ee..0000000 --- a/numpy21.patch +++ /dev/null @@ -1,389 +0,0 @@ -From 5f2a3d60fc9c1e25bec9fd6de0b0b8bae6f142da Mon Sep 17 00:00:00 2001 -From: kc611 -Date: Mon, 30 Sep 2024 23:08:18 +0530 -Subject: [PATCH 01/22] Added NumPy 2.1 Support - ---- - numba/cpython/randomimpl.py | 6 ++- - numba/cuda/tests/cudapy/test_debug.py | 2 +- - numba/np/arrayobj.py | 6 +-- - numba/np/math/numbers.py | 5 +++ - numba/np/npyfuncs.py | 58 +++++++++++++++++---------- - numba/np/old_arraymath.py | 2 + - numba/np/random/old_distributions.py | 4 +- - numba/np/ufunc_db.py | 36 +++++++++++++++++ - numba/tests/test_array_methods.py | 19 ++++++--- - 9 files changed, 105 insertions(+), 33 deletions(-) - -Index: numba-0.60.0/numba/cpython/randomimpl.py -=================================================================== ---- numba-0.60.0.orig/numba/cpython/randomimpl.py -+++ numba-0.60.0/numba/cpython/randomimpl.py -@@ -17,7 +17,7 @@ from numba.core.imputils import (Registr - from numba.core.typing import signature - from numba.core import types, cgutils - from numba.core.errors import NumbaTypeError -- -+from numba.np.random._constants import LONG_MAX - - registry = Registry('randomimpl') - lower = registry.lower -@@ -1798,6 +1798,10 @@ def zipf_impl(a): - U = 1.0 - np.random.random() - V = np.random.random() - X = int(math.floor(U ** (-1.0 / am1))) -+ -+ if (X > LONG_MAX or X < 1.0): -+ continue -+ - T = (1.0 + 1.0 / X) ** am1 - if X >= 1 and V * X * (T - 1.0) / (b - 1.0) <= (T / b): - return X -Index: numba-0.60.0/numba/np/arrayobj.py -=================================================================== ---- numba-0.60.0.orig/numba/np/arrayobj.py -+++ numba-0.60.0/numba/np/arrayobj.py -@@ -1932,17 +1932,23 @@ def numpy_geomspace(start, stop, num=50) - raise ValueError('Geometric sequence cannot include zero') - start = result_dtype(start) - stop = result_dtype(stop) -- both_imaginary = (start.real == 0) & (stop.real == 0) -- both_negative = (np.sign(start) == -1) & (np.sign(stop) == -1) -- out_sign = 1 -- if both_imaginary: -- start = start.imag -- stop = stop.imag -- out_sign = 1j -- if both_negative: -- start = -start -- stop = -stop -- out_sign = -out_sign -+ if numpy_version < (2, 0): -+ both_imaginary = (start.real == 0) & (stop.real == 0) -+ both_negative = (np.sign(start) == -1) & (np.sign(stop) == -1) -+ out_sign = 1 -+ if both_imaginary: -+ start = start.imag -+ stop = stop.imag -+ out_sign = 1j -+ if both_negative: -+ start = -start -+ stop = -stop -+ out_sign = -out_sign -+ else: -+ out_sign = np.sign(start) -+ start /= out_sign -+ stop /= out_sign -+ - logstart = np.log10(start) - logstop = np.log10(stop) - result = np.logspace(logstart, logstop, num) -@@ -2144,11 +2150,18 @@ def array_reshape_vararg(context, builde - return array_reshape(context, builder, new_sig, new_args) - - --@overload(np.reshape) --def np_reshape(a, newshape): -- def np_reshape_impl(a, newshape): -- return a.reshape(newshape) -- return np_reshape_impl -+if numpy_version < (2, 1): -+ @overload(np.reshape) -+ def np_reshape(a, newshape): -+ def np_reshape_impl(a, newshape): -+ return a.reshape(newshape) -+ return np_reshape_impl -+else: -+ @overload(np.reshape) -+ def np_reshape(a, shape): -+ def np_reshape_impl(a, shape): -+ return a.reshape(shape) -+ return np_reshape_impl - - - @overload(np.resize) -Index: numba-0.60.0/numba/np/math/numbers.py -=================================================================== ---- numba-0.60.0.orig/numba/np/math/numbers.py -+++ numba-0.60.0/numba/np/math/numbers.py -@@ -397,6 +397,11 @@ def int_abs_impl(context, builder, sig, - return impl_ret_untracked(context, builder, sig.return_type, res) - - -+def identity_impl(context, builder, sig, args): -+ [x] = args -+ return impl_ret_untracked(context, builder, sig.return_type, x) -+ -+ - def uint_abs_impl(context, builder, sig, args): - [x] = args - return impl_ret_untracked(context, builder, sig.return_type, x) -Index: numba-0.60.0/numba/np/npyfuncs.py -=================================================================== ---- numba-0.60.0.orig/numba/np/npyfuncs.py -+++ numba-0.60.0/numba/np/npyfuncs.py -@@ -16,6 +16,7 @@ from numba.core import typing, types, er - from numba.core.extending import register_jitable - from numba.np import npdatetime - from numba.np.math import cmathimpl, mathimpl, numbers -+from numba.np.numpy_support import numpy_version - - # some NumPy constants. Note that we could generate some of them using - # the math library, but having the values copied from npy_math seems to -@@ -580,29 +581,42 @@ def np_complex_sign_impl(context, builde - # equivalent to complex sign in NumPy's sign - # but implemented via selects, balancing the 4 cases. - _check_arity_and_homogeneity(sig, args, 1) -- op = args[0] -- ty = sig.args[0] -- float_ty = ty.underlying_float - -- ZERO = context.get_constant(float_ty, 0.0) -- ONE = context.get_constant(float_ty, 1.0) -- MINUS_ONE = context.get_constant(float_ty, -1.0) -- NAN = context.get_constant(float_ty, float('nan')) -- result = context.make_complex(builder, ty) -- result.real = ZERO -- result.imag = ZERO -- -- cmp_sig = typing.signature(types.boolean, *[ty] * 2) -- cmp_args = [op, result._getvalue()] -- arg1_ge_arg2 = np_complex_ge_impl(context, builder, cmp_sig, cmp_args) -- arg1_eq_arg2 = np_complex_eq_impl(context, builder, cmp_sig, cmp_args) -- arg1_lt_arg2 = np_complex_lt_impl(context, builder, cmp_sig, cmp_args) -- -- real_when_ge = builder.select(arg1_eq_arg2, ZERO, ONE) -- real_when_nge = builder.select(arg1_lt_arg2, MINUS_ONE, NAN) -- result.real = builder.select(arg1_ge_arg2, real_when_ge, real_when_nge) -+ if numpy_version >= (2, 0): -+ # NumPy >= 2.0.0 -+ def complex_sign(z): -+ abs = math.hypot(z.real, z.imag) -+ if abs == 0: -+ return 0 + 0j -+ else: -+ return z / abs -+ -+ res = context.compile_internal(builder, complex_sign, sig, args) -+ return impl_ret_untracked(context, builder, sig.return_type, res) -+ else: -+ op = args[0] -+ ty = sig.args[0] -+ result = context.make_complex(builder, ty) -+ float_ty = ty.underlying_float -+ -+ ZERO = context.get_constant(float_ty, 0.0) -+ ONE = context.get_constant(float_ty, 1.0) -+ MINUS_ONE = context.get_constant(float_ty, -1.0) -+ NAN = context.get_constant(float_ty, float('nan')) -+ -+ result.real = ZERO -+ result.imag = ZERO -+ cmp_sig = typing.signature(types.boolean, *[ty] * 2) -+ cmp_args = [op, result._getvalue()] -+ arg1_ge_arg2 = np_complex_ge_impl(context, builder, cmp_sig, cmp_args) -+ arg1_eq_arg2 = np_complex_eq_impl(context, builder, cmp_sig, cmp_args) -+ arg1_lt_arg2 = np_complex_lt_impl(context, builder, cmp_sig, cmp_args) -+ -+ real_when_ge = builder.select(arg1_eq_arg2, ZERO, ONE) -+ real_when_nge = builder.select(arg1_lt_arg2, MINUS_ONE, NAN) -+ result.real = builder.select(arg1_ge_arg2, real_when_ge, real_when_nge) - -- return result._getvalue() -+ return result._getvalue() - - - ######################################################################## -Index: numba-0.60.0/numba/np/ufunc_db.py -=================================================================== ---- numba-0.60.0.orig/numba/np/ufunc_db.py -+++ numba-0.60.0/numba/np/ufunc_db.py -@@ -583,16 +583,58 @@ def _fill_ufunc_db(ufunc_db): - 'f->f': npyfuncs.np_real_floor_impl, - 'd->d': npyfuncs.np_real_floor_impl, - } -+ if numpy_version >= (2, 1): -+ ufunc_db[np.floor].update({ -+ '?->?': numbers.identity_impl, -+ 'b->b': numbers.identity_impl, -+ 'B->B': numbers.identity_impl, -+ 'h->h': numbers.identity_impl, -+ 'H->H': numbers.identity_impl, -+ 'i->i': numbers.identity_impl, -+ 'I->I': numbers.identity_impl, -+ 'l->l': numbers.identity_impl, -+ 'L->L': numbers.identity_impl, -+ 'q->q': numbers.identity_impl, -+ 'Q->Q': numbers.identity_impl, -+ }) - - ufunc_db[np.ceil] = { - 'f->f': npyfuncs.np_real_ceil_impl, - 'd->d': npyfuncs.np_real_ceil_impl, - } -+ if numpy_version >= (2, 1): -+ ufunc_db[np.ceil].update({ -+ '?->?': numbers.identity_impl, -+ 'b->b': numbers.identity_impl, -+ 'B->B': numbers.identity_impl, -+ 'h->h': numbers.identity_impl, -+ 'H->H': numbers.identity_impl, -+ 'i->i': numbers.identity_impl, -+ 'I->I': numbers.identity_impl, -+ 'l->l': numbers.identity_impl, -+ 'L->L': numbers.identity_impl, -+ 'q->q': numbers.identity_impl, -+ 'Q->Q': numbers.identity_impl, -+ }) - - ufunc_db[np.trunc] = { - 'f->f': npyfuncs.np_real_trunc_impl, - 'd->d': npyfuncs.np_real_trunc_impl, - } -+ if numpy_version >= (2, 1): -+ ufunc_db[np.trunc].update({ -+ '?->?': numbers.identity_impl, -+ 'b->b': numbers.identity_impl, -+ 'B->B': numbers.identity_impl, -+ 'h->h': numbers.identity_impl, -+ 'H->H': numbers.identity_impl, -+ 'i->i': numbers.identity_impl, -+ 'I->I': numbers.identity_impl, -+ 'l->l': numbers.identity_impl, -+ 'L->L': numbers.identity_impl, -+ 'q->q': numbers.identity_impl, -+ 'Q->Q': numbers.identity_impl, -+ }) - - ufunc_db[np.fabs] = { - 'f->f': npyfuncs.np_real_fabs_impl, -Index: numba-0.60.0/numba/tests/test_array_methods.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_array_methods.py -+++ numba-0.60.0/numba/tests/test_array_methods.py -@@ -774,13 +774,20 @@ class TestArrayMethods(MemoryLeakMixin, - check_arr(arr.reshape((2, 3, 4))) - check_arr(arr.reshape((2, 3, 4)).T) - check_arr(arr.reshape((2, 3, 4))[::2]) -- for v in (0.0, 1.5, float('nan')): -- arr = np.array([v]).reshape(()) -- check_arr(arr) - - arr = np.array(["Hello", "", "world"]) - check_arr(arr) - -+ for v in (0.0, 1.5, float('nan')): -+ arr = np.array([v]).reshape(()) -+ if numpy_version < (2, 1): -+ check_arr(arr) -+ else: -+ with self.assertRaises(ValueError) as raises: -+ njit((typeof(arr),))(pyfunc) -+ self.assertEqual(str(raises.exception), -+ "Calling nonzero on 0d arrays is not allowed. Use np.atleast_1d(scalar).nonzero() instead.") -+ - def test_array_nonzero(self): - self.check_nonzero(array_nonzero) - -Index: numba-0.60.0/docs/upcoming_changes/9741.highlight.rst -=================================================================== ---- /dev/null -+++ numba-0.60.0/docs/upcoming_changes/9741.highlight.rst -@@ -0,0 +1,4 @@ -+Added Support for NumPy 2.1 -+--------------------------- -+ -+This release adds support for NumPy 2.1 (excluding the NEP-050 semantics). -Index: numba-0.60.0/numba/tests/test_ufuncs.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_ufuncs.py -+++ numba-0.60.0/numba/tests/test_ufuncs.py -@@ -18,7 +18,6 @@ from numba.np import numpy_support - from numba.core.registry import cpu_target - from numba.core.base import BaseContext - from numba.np import ufunc_db --from numba.tests.support import expected_failure_np2 - - is32bits = tuple.__itemsize__ == 4 - iswindows = sys.platform.startswith('win32') -@@ -1696,8 +1695,6 @@ class TestLoopTypesComplex(_LoopTypesTes - - - TestLoopTypesComplex.autogenerate() --expected_failure_np2(TestLoopTypesComplex.test_sign_F_F) --expected_failure_np2(TestLoopTypesComplex.test_sign_D_D) - - - class TestLoopTypesDatetime(_LoopTypesTester): -Index: numba-0.60.0/numba/core/typing/arraydecl.py -=================================================================== ---- numba-0.60.0.orig/numba/core/typing/arraydecl.py -+++ numba-0.60.0/numba/core/typing/arraydecl.py -@@ -415,6 +415,11 @@ class ArrayAttribute(AttributeTemplate): - def resolve_nonzero(self, ary, args, kws): - assert not args - assert not kws -+ if ary.ndim == 0 and numpy_version >= (2, 1): -+ raise ValueError( -+ "Calling nonzero on 0d arrays is not allowed." -+ " Use np.atleast_1d(scalar).nonzero() instead." -+ ) - # 0-dim arrays return one result array - ndim = max(ary.ndim, 1) - retty = types.UniTuple(types.Array(types.intp, 1, 'C'), ndim) -Index: numba-0.60.0/numba/np/random/_constants.py -=================================================================== ---- numba-0.60.0.orig/numba/np/random/_constants.py -+++ numba-0.60.0/numba/np/random/_constants.py -@@ -1,4 +1,5 @@ - import numpy as np -+import ctypes - - # These constants are directly obtained from: - # https://github.com/numpy/numpy/blob/caccd283941b0bade7b71056138ded5379b1625f/numpy/random/src/distributions/ziggurat_constants.h -@@ -1222,6 +1223,7 @@ UINT8_MAX = 255 - UINT16_MAX = 65535 - UINT32_MAX = 4294967295 - UINT64_MAX = 18446744073709551615 -+LONG_MAX = (1 << ( 8 * ctypes.sizeof(ctypes.c_long) - 1)) - 1 - - LS2PI = 0.91893853320467267 - TWELFTH = 0.083333333333333333333333 -Index: numba-0.60.0/numba/__init__.py -=================================================================== ---- numba-0.60.0.orig/numba/__init__.py -+++ numba-0.60.0/numba/__init__.py -@@ -34,13 +34,13 @@ def _ensure_critical_deps(): - import numpy as np - numpy_version = extract_version(np) - -- if numpy_version < (1, 22): -- msg = (f"Numba needs NumPy 1.22 or greater. Got NumPy " -+ if numpy_version < (1, 24): -+ msg = (f"Numba needs NumPy 1.24 or greater. Got NumPy " - f"{numpy_version[0]}.{numpy_version[1]}.") - raise ImportError(msg) - -- if numpy_version > (2, 0): -- msg = (f"Numba needs NumPy 2.0 or less. Got NumPy " -+ if numpy_version > (2, 1): -+ msg = (f"Numba needs NumPy 2.1 or less. Got NumPy " - f"{numpy_version[0]}.{numpy_version[1]}.") - raise ImportError(msg) - -Index: numba-0.60.0/numba/np/random/distributions.py -=================================================================== ---- a/numba/np/random/distributions.py -+++ b/numba/np/random/distributions.py -@@ -394,8 +394,10 @@ def random_geometric(bitgen, p): - def random_zipf(bitgen, a): - am1 = a - 1.0 - b = pow(2.0, am1) -+ Umin = pow(INT64_MAX, -am1) - while 1: -- U = 1.0 - next_double(bitgen) -+ U01 = next_double(bitgen) -+ U = U01*Umin + (1 - U01) - V = next_double(bitgen) - X = np.floor(pow(U, -1.0 / am1)) - if (X > INT64_MAX or X < 1.0): diff --git a/py313.patch b/py313.patch deleted file mode 100644 index 8ea9ce7..0000000 --- a/py313.patch +++ /dev/null @@ -1,4127 +0,0 @@ -From 3e89582a41fc2712a0ce86528be98cf3dd768a23 Mon Sep 17 00:00:00 2001 -From: Siu Kwan Lam <1929845+sklam@users.noreply.github.com> -Date: Tue, 16 Jan 2024 14:31:01 -0600 -Subject: [PATCH 01/61] Minimal changes to get compiling - -Added pythoncapi_compat.h from https://github.com/python/pythoncapi-compat ---- - numba/_devicearray.cpp | 2 +- - numba/_dispatcher.cpp | 8 +- - numba/_dynfunc.c | 12 +- - numba/_helperlib.c | 4 +- - numba/_pymodule.h | 4 + - numba/_typeof.cpp | 8 + - numba/core/runtime/_nrt_python.c | 2 +- - numba/experimental/jitclass/_box.c | 2 +- - numba/mviewbuf.c | 2 +- - numba/np/ufunc/_internal.c | 4 +- - numba/pythoncapi_compat.h | 1114 ++++++++++++++++++++++++++++ - setup.py | 2 +- - 12 files changed, 1148 insertions(+), 16 deletions(-) - create mode 100644 numba/pythoncapi_compat.h - -Index: numba-0.60.0/numba/_devicearray.cpp -=================================================================== ---- numba-0.60.0.orig/numba/_devicearray.cpp -+++ numba-0.60.0/numba/_devicearray.cpp -@@ -96,7 +96,7 @@ PyTypeObject DeviceArrayType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/_dispatcher.cpp -=================================================================== ---- numba-0.60.0.orig/numba/_dispatcher.cpp -+++ numba-0.60.0/numba/_dispatcher.cpp -@@ -27,7 +27,7 @@ - * - */ - --#if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 12) -+#if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 12) || (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 13) - - #ifndef Py_BUILD_CORE - #define Py_BUILD_CORE 1 -@@ -39,7 +39,10 @@ - # undef HAVE_STD_ATOMIC - #endif - #undef _PyGC_FINALIZED --#include "internal/pycore_atomic.h" -+ -+#if (PY_MINOR_VERSION == 12) -+ #include "internal/pycore_atomic.h" -+#endif - #include "internal/pycore_interp.h" - #include "internal/pycore_pyerrors.h" - #include "internal/pycore_instruments.h" -@@ -780,7 +783,7 @@ call_cfunc(Dispatcher *self, PyObject *c - } - } - --#elif (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 12) -+#elif (PY_MAJOR_VERSION >= 3) && ((PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13)) - - // Python 3.12 has a completely new approach to tracing and profiling due to - // the new `sys.monitoring` system. -@@ -1589,7 +1592,7 @@ static PyTypeObject DispatcherType = { - 0, /* tp_version_tag */ - 0, /* tp_finalize */ - 0, /* tp_vectorcall */ --#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) -+#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) || (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 13) - /* This was introduced first in 3.12 - * https://github.com/python/cpython/issues/91051 - */ -@@ -1599,7 +1602,7 @@ static PyTypeObject DispatcherType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/_dynfunc.c -=================================================================== ---- numba-0.60.0.orig/numba/_dynfunc.c -+++ numba-0.60.0/numba/_dynfunc.c -@@ -7,6 +7,12 @@ - - #include - -+ -+// if python version is 3.13 -+#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 13) -+ #include "pythoncapi_compat.h" -+ #define _Py_IsFinalizing Py_IsFinalizing -+#endif - /* NOTE: EnvironmentObject and ClosureObject must be kept in sync with - * the definitions in numba/targets/base.py (EnvBody and ClosureBody). - */ -@@ -146,7 +152,7 @@ static PyTypeObject EnvironmentType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -@@ -265,7 +271,7 @@ static PyTypeObject ClosureType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -@@ -485,7 +491,7 @@ static PyTypeObject GeneratorType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/_helperlib.c -=================================================================== ---- numba-0.60.0.orig/numba/_helperlib.c -+++ numba-0.60.0/numba/_helperlib.c -@@ -293,7 +293,7 @@ numba_recreate_record(void *pdata, int s - return NULL; - } - -- numpy = PyImport_ImportModuleNoBlock("numpy"); -+ numpy = PyImport_ImportModule("numpy"); - if (!numpy) goto CLEANUP; - - numpy_record = PyObject_GetAttrString(numpy, "record"); -@@ -833,7 +833,7 @@ static void traceback_add(const char *fu - if (!frame) - goto error; - --#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) /* 3.12 */ -+#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) || (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 13) /* 3.12 or 3.13 */ - #elif (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 11) /* 3.11 */ - - /* unsafe cast to our copy of _frame to access the f_lineno field */ -@@ -851,7 +851,7 @@ static void traceback_add(const char *fu - Py_DECREF(frame); - return; - --#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) /* 3.12 */ -+#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 12) || (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION == 13) /* 3.12 or 3.13 */ - error: - _PyErr_ChainExceptions1(exc); - #elif (PY_MAJOR_VERSION == 3) && ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11)) /* 3.11 and below */ -Index: numba-0.60.0/numba/_pymodule.h -=================================================================== ---- numba-0.60.0.orig/numba/_pymodule.h -+++ numba-0.60.0/numba/_pymodule.h -@@ -29,4 +29,7 @@ - PyObject_SetAttrString(m, #name, tmp); \ - Py_DECREF(tmp); } while (0) - -+ -+#define NB_SUPPORTED_PYTHON_MINOR ((PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12) || (PY_MINOR_VERSION == 13)) -+ - #endif /* NUMBA_PY_MODULE_H_ */ -Index: numba-0.60.0/numba/_typeof.cpp -=================================================================== ---- numba-0.60.0.orig/numba/_typeof.cpp -+++ numba-0.60.0/numba/_typeof.cpp -@@ -16,6 +16,14 @@ - #include - #endif - -+#if (PY_MAJOR_VERSION >= 3) && (PY_MINOR_VERSION == 13) -+ #ifndef Py_BUILD_CORE -+ #define Py_BUILD_CORE 1 -+ #endif -+ #include "internal/pycore_setobject.h" // _PySet_NextEntry() -+#endif -+ -+ - /* Cached typecodes for basic scalar types */ - static int tc_int8; - static int tc_int16; -Index: numba-0.60.0/numba/core/runtime/_nrt_python.c -=================================================================== ---- numba-0.60.0.orig/numba/core/runtime/_nrt_python.c -+++ numba-0.60.0/numba/core/runtime/_nrt_python.c -@@ -229,7 +229,7 @@ static PyTypeObject MemInfoType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/experimental/jitclass/_box.c -=================================================================== ---- numba-0.60.0.orig/numba/experimental/jitclass/_box.c -+++ numba-0.60.0/numba/experimental/jitclass/_box.c -@@ -110,7 +110,7 @@ static PyTypeObject BoxType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/mviewbuf.c -=================================================================== ---- numba-0.60.0.orig/numba/mviewbuf.c -+++ numba-0.60.0/numba/mviewbuf.c -@@ -344,7 +344,7 @@ static PyTypeObject MemAllocType = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/np/ufunc/_internal.c -=================================================================== ---- numba-0.60.0.orig/numba/np/ufunc/_internal.c -+++ numba-0.60.0/numba/np/ufunc/_internal.c -@@ -100,7 +100,7 @@ PyTypeObject PyUFuncCleaner_Type = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -@@ -753,7 +753,7 @@ PyTypeObject PyDUFunc_Type = { - /* WARNING: Do not remove this, only modify it! It is a version guard to - * act as a reminder to update this struct on Python version update! */ - #if (PY_MAJOR_VERSION == 3) --#if ! ((PY_MINOR_VERSION == 9) || (PY_MINOR_VERSION == 10) || (PY_MINOR_VERSION == 11) || (PY_MINOR_VERSION == 12)) -+#if ! (NB_SUPPORTED_PYTHON_MINOR) - #error "Python minor version is not supported." - #endif - #else -Index: numba-0.60.0/numba/core/bytecode.py -=================================================================== ---- numba-0.60.0.orig/numba/core/bytecode.py -+++ numba-0.60.0/numba/core/bytecode.py -@@ -9,7 +9,7 @@ from numba.core import errors, utils, se - from numba.core.utils import PYVERSION - - --if PYVERSION in ((3, 12), ): -+if PYVERSION in ((3, 12), (3, 13)): - from opcode import _inline_cache_entries - # Instruction/opcode length in bytes - INSTR_LEN = 2 -@@ -104,7 +104,12 @@ class ByteCodeInst(object): - # https://bugs.python.org/issue27129 - # https://github.com/python/cpython/pull/25069 - assert self.is_jump -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 13),): -+ if self.opcode in (dis.opmap[k] -+ for k in ["JUMP_BACKWARD", -+ "JUMP_BACKWARD_NO_INTERRUPT"]): -+ return self.next - (self.arg * 2) -+ elif PYVERSION in ((3, 12),): - if self.opcode in (dis.opmap[k] - for k in ["JUMP_BACKWARD"]): - return self.offset - (self.arg - 1) * 2 -@@ -121,7 +126,7 @@ class ByteCodeInst(object): - else: - raise NotImplementedError(PYVERSION) - -- if PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)): - if self.opcode in JREL_OPS: - return self.next + self.arg * 2 - else: -@@ -160,7 +165,7 @@ OPCODE_NOP = dis.opname.index('NOP') - - - # Adapted from Lib/dis.py --def _unpack_opargs(code): -+def _unpack_opargs_pre_3_13(code): - """ - Returns a 4-int-tuple of - (bytecode offset, opcode, argument, offset of next bytecode). -@@ -176,7 +181,7 @@ def _unpack_opargs(code): - for j in range(ARG_LEN): - arg |= code[i + j] << (8 * j) - i += ARG_LEN -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12),): - # Python 3.12 introduced cache slots. We need to account for - # cache slots when we determine the offset of the next opcode. - # The number of cache slots is specific to each opcode and can -@@ -200,7 +205,7 @@ def _unpack_opargs(code): - else: - arg = None - i += NO_ARG_LEN -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12),): - # Python 3.12 introduced cache slots. We need to account for - # cache slots when we determine the offset of the next opcode. - # The number of cache slots is specific to each opcode and can -@@ -216,6 +221,80 @@ def _unpack_opargs(code): - offset = i # Mark inst offset at first extended - - -+# Adapted from Lib/dis.py -+def _unpack_opargs_pre_3_13(code): -+ """ -+ Returns a 4-int-tuple of -+ (bytecode offset, opcode, argument, offset of next bytecode). -+ """ -+ extended_arg = 0 -+ n = len(code) -+ offset = i = 0 -+ while i < n: -+ op = code[i] -+ i += CODE_LEN -+ if op >= HAVE_ARGUMENT: -+ arg = code[i] | extended_arg -+ for j in range(ARG_LEN): -+ arg |= code[i + j] << (8 * j) -+ i += ARG_LEN -+ if PYVERSION in ((3, 12),): -+ # Python 3.12 introduced cache slots. We need to account for -+ # cache slots when we determine the offset of the next opcode. -+ # The number of cache slots is specific to each opcode and can -+ # be looked up in the _inline_cache_entries dictionary. -+ i += _inline_cache_entries[op] * INSTR_LEN -+ elif PYVERSION in ((3, 10), (3, 11)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ if op == EXTENDED_ARG: -+ # This is a deviation from what dis does... -+ # In python 3.11 it seems like EXTENDED_ARGs appear more often -+ # and are also used as jump targets. So as to not have to do -+ # "book keeping" for where EXTENDED_ARGs have been "skipped" -+ # they are replaced with NOPs so as to provide a legal jump -+ # target and also ensure that the bytecode offsets are correct. -+ yield (offset, OPCODE_NOP, arg, i) -+ extended_arg = arg << 8 * ARG_LEN -+ offset = i -+ continue -+ else: -+ arg = None -+ i += NO_ARG_LEN -+ if PYVERSION in ((3, 12),): -+ # Python 3.12 introduced cache slots. We need to account for -+ # cache slots when we determine the offset of the next opcode. -+ # The number of cache slots is specific to each opcode and can -+ # be looked up in the _inline_cache_entries dictionary. -+ i += _inline_cache_entries[op] * INSTR_LEN -+ elif PYVERSION in ((3, 10), (3, 11)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ -+ extended_arg = 0 -+ yield (offset, op, arg, i) -+ offset = i # Mark inst offset at first extended -+ -+ -+if PYVERSION in ((3, 13),): -+ -+ def _unpack_opargs(code): -+ buf = [] -+ for i, start_offset, op, arg in dis._unpack_opargs(code): -+ buf.append((start_offset, op, arg)) -+ for i, (start_offset, op, arg) in enumerate(buf): -+ if i + 1 < len(buf): -+ next_offset = buf[i + 1][0] -+ else: -+ next_offset = len(code) -+ yield (start_offset, op, arg, next_offset) -+ -+else: -+ _unpack_opargs = _unpack_opargs_pre_3_13 -+ -+ - def _patched_opargs(bc_stream): - """Patch the bytecode stream. - -@@ -298,7 +377,7 @@ class _ByteCode(object): - # Start with first bytecode's lineno - known = code.co_firstlineno - for inst in table.values(): -- if inst.lineno >= 0: -+ if inst.lineno is not None and inst.lineno >= 0: - known = inst.lineno - else: - inst.lineno = known -@@ -363,7 +442,7 @@ class _ByteCode(object): - - - def _fix_LOAD_GLOBAL_arg(arg): -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - return arg >> 1 - elif PYVERSION in ((3, 9), (3, 10)): - return arg -@@ -452,8 +531,15 @@ class ByteCodePy312(ByteCodePy311): - entirely along with the dead exceptions that it points to. - A pair of exception that sandwiches these exception will - also be merged into a single exception. -- """ - -+ Update for Python 3.13, the ending of the pattern has a extra -+ POP_TOP: -+ -+ ... -+ END_FOR -+ POP_TOP -+ SWAP(2) -+ """ - def pop_and_merge_exceptions(entries: list, - entry_to_remove: _ExceptionTableEntry): - lower_entry_idx = entries.index(entry_to_remove) - 1 -@@ -505,17 +591,34 @@ class ByteCodePy312(ByteCodePy311): - if not next_inst.opname == "FOR_ITER": - continue - -- # Check end of pattern, two instructions. -- # Check for the corresponding END_FOR, exception table end is -- # non-inclusive, so subtract one. -- index = self.ordered_offsets.index(entry.end) -- curr_inst = self.table[self.ordered_offsets[index - 1]] -- if not curr_inst.opname == "END_FOR": -- continue -- # END_FOR must be followed by SWAP(2) -- next_inst = self.table[self.ordered_offsets[index]] -- if not next_inst.opname == "SWAP" and next_inst.arg == 2: -- continue -+ if PYVERSION == (3, 13): -+ # Check end of pattern, two instructions. -+ # Check for the corresponding END_FOR, exception table end -+ # is non-inclusive, so subtract one. -+ index = self.ordered_offsets.index(entry.end) -+ curr_inst = self.table[self.ordered_offsets[index - 2]] -+ if not curr_inst.opname == "END_FOR": -+ continue -+ next_inst = self.table[self.ordered_offsets[index - 1]] -+ if not next_inst.opname == "POP_TOP": -+ continue -+ # END_FOR must be followed by SWAP(2) -+ next_inst = self.table[self.ordered_offsets[index]] -+ if not next_inst.opname == "SWAP" and next_inst.arg == 2: -+ continue -+ else: -+ assert PYVERSION < (3, 13) -+ # Check end of pattern, two instructions. -+ # Check for the corresponding END_FOR, exception table end -+ # is non-inclusive, so subtract one. -+ index = self.ordered_offsets.index(entry.end) -+ curr_inst = self.table[self.ordered_offsets[index - 1]] -+ if not curr_inst.opname == "END_FOR": -+ continue -+ # END_FOR must be followed by SWAP(2) -+ next_inst = self.table[self.ordered_offsets[index]] -+ if not next_inst.opname == "SWAP" and next_inst.arg == 2: -+ continue - # If all conditions are met that means this exception entry - # is for a list/dict/set comprehension and can be removed. - # Also if there exist exception entries above and below this -@@ -528,7 +631,7 @@ class ByteCodePy312(ByteCodePy311): - - if PYVERSION == (3, 11): - ByteCode = ByteCodePy311 --elif PYVERSION == (3, 12): -+elif PYVERSION in ((3, 12), (3, 13),): - ByteCode = ByteCodePy312 - elif PYVERSION < (3, 11): - ByteCode = _ByteCode -Index: numba-0.60.0/numba/core/byteflow.py -=================================================================== ---- numba-0.60.0.orig/numba/core/byteflow.py -+++ numba-0.60.0/numba/core/byteflow.py -@@ -10,7 +10,7 @@ from functools import total_ordering - from numba.core.utils import UniqueDict, PYVERSION, ALL_BINOPS_TO_OPERATORS - from numba.core.controlflow import NEW_BLOCKERS, CFGraph - from numba.core.ir import Loc --from numba.core.errors import UnsupportedError -+from numba.core.errors import UnsupportedBytecodeError - - - _logger = logging.getLogger(__name__) -@@ -24,7 +24,7 @@ _NO_RAISE_OPS = frozenset({ - 'PRECALL', - }) - --if PYVERSION in ((3, 12), ): -+if PYVERSION in ((3, 12), (3, 13)): - from enum import Enum - - # Operands for CALL_INTRINSIC_1 -@@ -149,7 +149,7 @@ class Flow(object): - self.block_infos[state.pc_initial] = si = adapt_state_infos(state) - _logger.debug("block_infos %s:\n%s", state, si) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def _run_handle_exception(self, runner, state): - if not state.in_with() and ( - state.has_active_try() and -@@ -312,7 +312,7 @@ class Flow(object): - msg = ("The 'with (context manager) as " - "(variable):' construct is not " - "supported.") -- raise UnsupportedError(msg) -+ raise UnsupportedBytecodeError(msg) - - - def _is_null_temp_reg(reg): -@@ -331,7 +331,7 @@ class TraceRunner(object): - return Loc(self.debug_filename, lineno) - - def dispatch(self, state): -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - if state._blockstack: - state: State - while state._blockstack: -@@ -354,7 +354,8 @@ class TraceRunner(object): - fn(state, inst) - else: - msg = "Use of unsupported opcode (%s) found" % inst.opname -- raise UnsupportedError(msg, loc=self.get_debug_loc(inst.lineno)) -+ raise UnsupportedBytecodeError(msg, -+ loc=self.get_debug_loc(inst.lineno)) - - def _adjust_except_stack(self, state): - """ -@@ -405,6 +406,15 @@ class TraceRunner(object): - state.push(state.make_temp()) - state.append(inst) - -+ if PYVERSION in ((3, 13),): -+ def op_FORMAT_SIMPLE(self, state, inst): -+ assert PYVERSION == (3, 13) -+ value = state.pop() -+ strvar = state.make_temp() -+ res = state.make_temp() -+ state.append(inst, value=value, res=res, strvar=strvar) -+ state.push(res) -+ - def op_FORMAT_VALUE(self, state, inst): - """ - FORMAT_VALUE(flags): flags argument specifies format spec which is -@@ -415,7 +425,8 @@ class TraceRunner(object): - """ - if inst.arg != 0: - msg = "format spec in f-strings not supported yet" -- raise UnsupportedError(msg, loc=self.get_debug_loc(inst.lineno)) -+ raise UnsupportedBytecodeError(msg, -+ loc=self.get_debug_loc(inst.lineno)) - value = state.pop() - strvar = state.make_temp() - res = state.make_temp() -@@ -442,7 +453,27 @@ class TraceRunner(object): - def op_POP_TOP(self, state, inst): - state.pop() - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 13),): -+ def op_TO_BOOL(self, state, inst): -+ res = state.make_temp() -+ tos = state.pop() -+ state.append(inst, val=tos, res=res) -+ state.push(res) -+ -+ elif PYVERSION < (3, 13): -+ pass -+ -+ if PYVERSION in ((3, 13),): -+ def op_LOAD_GLOBAL(self, state, inst): -+ # Ordering of the global value and NULL is swapped in Py3.13 -+ res = state.make_temp() -+ idx = inst.arg >> 1 -+ state.append(inst, idx=idx, res=res) -+ state.push(res) -+ # ignoring the NULL -+ if inst.arg & 1: -+ state.push(state.make_null()) -+ elif PYVERSION in ((3, 11), (3, 12)): - def op_LOAD_GLOBAL(self, state, inst): - res = state.make_temp() - idx = inst.arg >> 1 -@@ -471,30 +502,89 @@ class TraceRunner(object): - state.push(res) - - def op_LOAD_CONST(self, state, inst): -- res = state.make_temp("const") -+ # append const index for interpreter to read the const value -+ res = state.make_temp("const") + f".{inst.arg}" - state.push(res) - state.append(inst, res=res) - - def op_LOAD_ATTR(self, state, inst): - item = state.pop() -- if PYVERSION in ((3, 12), ): -+ res = state.make_temp() -+ if PYVERSION in ((3, 13),): -+ state.push(res) # the attr -+ if inst.arg & 1: -+ state.push(state.make_null()) -+ elif PYVERSION in ((3, 12),): - if inst.arg & 1: - state.push(state.make_null()) -+ state.push(res) - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): -- pass -+ state.push(res) - else: - raise NotImplementedError(PYVERSION) -- res = state.make_temp() - state.append(inst, item=item, res=res) -- state.push(res) - - def op_LOAD_FAST(self, state, inst): -- name = state.get_varname(inst) -+ assert PYVERSION <= (3, 13) -+ if PYVERSION in ((3, 13), ): -+ try: -+ name = state.get_varname(inst) -+ except IndexError: # oparg is out of range -+ # Handle this like a LOAD_DEREF -+ # Assume MAKE_CELL and COPY_FREE_VARS has correctly setup the -+ # states. -+ # According to https://github.com/python/cpython/blob/9ac606080a0074cdf7589d9b7c9413a73e0ddf37/Objects/codeobject.c#L730C9-L759 # noqa E501 -+ # localsplus is locals + cells + freevars -+ bc = state._bytecode -+ num_varnames = len(bc.co_varnames) -+ num_freevars = len(bc.co_freevars) -+ num_cellvars = len(bc.co_cellvars) -+ max_fast_local = num_cellvars + num_freevars -+ assert 0 <= inst.arg - num_varnames < max_fast_local -+ res = state.make_temp() -+ state.append(inst, res=res, as_load_deref=True) -+ state.push(res) -+ return -+ else: -+ name = state.get_varname(inst) - res = state.make_temp(name) - state.append(inst, res=res) - state.push(res) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 13),): -+ def op_LOAD_FAST_LOAD_FAST(self, state, inst): -+ oparg = inst.arg -+ oparg1 = oparg >> 4 -+ oparg2 = oparg & 15 -+ name1 = state.get_varname_by_arg(oparg1) -+ name2 = state.get_varname_by_arg(oparg2) -+ res1 = state.make_temp(name1) -+ res2 = state.make_temp(name2) -+ state.append(inst, res1=res1, res2=res2) -+ state.push(res1) -+ state.push(res2) -+ -+ def op_STORE_FAST_LOAD_FAST(self, state, inst): -+ oparg = inst.arg -+ # oparg1 = oparg >> 4 # not needed -+ oparg2 = oparg & 15 -+ store_value = state.pop() -+ load_name = state.get_varname_by_arg(oparg2) -+ load_res = state.make_temp(load_name) -+ state.append(inst, store_value=store_value, load_res=load_res) -+ state.push(load_res) -+ -+ def op_STORE_FAST_STORE_FAST(self, state, inst): -+ value1 = state.pop() -+ value2 = state.pop() -+ state.append(inst, value1=value1, value2=value2) -+ -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ -+ if PYVERSION in ((3, 12), (3, 13)): - op_LOAD_FAST_CHECK = op_LOAD_FAST - op_LOAD_FAST_AND_CLEAR = op_LOAD_FAST - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): -@@ -753,7 +843,7 @@ class TraceRunner(object): - ) - state.push(res) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_BINARY_SLICE(self, state, inst): - end = state.pop() - start = state.pop() -@@ -771,7 +861,7 @@ class TraceRunner(object): - else: - raise NotImplementedError(PYVERSION) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_STORE_SLICE(self, state, inst): - end = state.pop() - start = state.pop() -@@ -804,7 +894,7 @@ class TraceRunner(object): - op_POP_JUMP_IF_TRUE = _op_POP_JUMP_IF - op_POP_JUMP_IF_FALSE = _op_POP_JUMP_IF - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - op_POP_JUMP_IF_NONE = _op_POP_JUMP_IF - op_POP_JUMP_IF_NOT_NONE = _op_POP_JUMP_IF - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): -@@ -853,6 +943,8 @@ class TraceRunner(object): - state.append(inst) - state.fork(pc=inst.get_jump_target()) - -+ op_JUMP_BACKWARD_NO_INTERRUPT = op_JUMP_BACKWARD -+ - def op_JUMP_ABSOLUTE(self, state, inst): - state.append(inst) - state.fork(pc=inst.get_jump_target()) -@@ -868,7 +960,7 @@ class TraceRunner(object): - state.append(inst, retval=state.pop(), castval=state.make_temp()) - state.terminate() - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_RETURN_CONST(self, state, inst): - res = state.make_temp("const") - state.append(inst, retval=res, castval=state.make_temp()) -@@ -884,14 +976,14 @@ class TraceRunner(object): - state.append(inst, value=val, res=res) - state.push(res) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_RAISE_VARARGS(self, state, inst): - if inst.arg == 0: - exc = None - # No re-raising within a try-except block. - # But we allow bare reraise. - if state.has_active_try(): -- raise UnsupportedError( -+ raise UnsupportedBytecodeError( - "The re-raising of an exception is not yet supported.", - loc=self.get_debug_loc(inst.lineno), - ) -@@ -915,7 +1007,7 @@ class TraceRunner(object): - if inst.arg == 0: - exc = None - if in_exc_block: -- raise UnsupportedError( -+ raise UnsupportedBytecodeError( - "The re-raising of an exception is not yet supported.", - loc=self.get_debug_loc(inst.lineno), - ) -@@ -940,7 +1032,10 @@ class TraceRunner(object): - blk = state.pop_block() - state.reset_stack(blk['entry_stack']) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 13),): -+ def op_END_FOR(self, state, inst): -+ state.pop() -+ elif PYVERSION in ((3, 12),): - def op_END_FOR(self, state, inst): - state.pop() - state.pop() -@@ -954,7 +1049,8 @@ class TraceRunner(object): - if inst.arg != 0: - msg = ('Unsupported use of a bytecode related to try..finally' - ' or a with-context') -- raise UnsupportedError(msg, loc=self.get_debug_loc(inst.lineno)) -+ raise UnsupportedBytecodeError(msg, -+ loc=self.get_debug_loc(inst.lineno)) - - def op_CALL_FINALLY(self, state, inst): - pass -@@ -1068,7 +1164,7 @@ class TraceRunner(object): - 'FINALLY', state, next=inst.next, end=inst.get_jump_target(), - ) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_POP_EXCEPT(self, state, inst): - state.pop() - -@@ -1076,7 +1172,7 @@ class TraceRunner(object): - def op_POP_EXCEPT(self, state, inst): - blk = state.pop_block() - if blk['kind'] not in {BlockKind('EXCEPT'), BlockKind('FINALLY')}: -- raise UnsupportedError( -+ raise UnsupportedBytecodeError( - f"POP_EXCEPT got an unexpected block: {blk['kind']}", - loc=self.get_debug_loc(inst.lineno), - ) -@@ -1117,16 +1213,24 @@ class TraceRunner(object): - def op_CALL(self, state, inst): - narg = inst.arg - args = list(reversed([state.pop() for _ in range(narg)])) -- callable_or_firstarg = state.pop() -- null_or_callable = state.pop() -- if _is_null_temp_reg(null_or_callable): -- callable = callable_or_firstarg -- else: -- callable = null_or_callable -- args = [callable_or_firstarg, *args] -+ if PYVERSION == (3, 13): -+ null_or_self = state.pop() -+ # position of the callable is fixed -+ callable = state.pop() -+ if not _is_null_temp_reg(null_or_self): -+ args = [null_or_self, *args] -+ kw_names = None -+ elif PYVERSION < (3, 13): -+ callable_or_firstarg = state.pop() -+ null_or_callable = state.pop() -+ if _is_null_temp_reg(null_or_callable): -+ callable = callable_or_firstarg -+ else: -+ callable = null_or_callable -+ args = [callable_or_firstarg, *args] -+ kw_names = state.pop_kw_names() - res = state.make_temp() - -- kw_names = state.pop_kw_names() - state.append(inst, func=callable, args=args, kw_names=kw_names, res=res) - state.push(res) - -@@ -1152,28 +1256,67 @@ class TraceRunner(object): - state.append(inst, func=func, args=args, names=names, res=res) - state.push(res) - -- def op_CALL_FUNCTION_EX(self, state, inst): -- if inst.arg & 1 and PYVERSION < (3, 10): -- errmsg = "CALL_FUNCTION_EX with **kwargs not supported" -- raise UnsupportedError(errmsg) -- if inst.arg & 1: -- varkwarg = state.pop() -- else: -- varkwarg = None -- vararg = state.pop() -- func = state.pop() -+ if PYVERSION in ((3, 13),): -+ def op_CALL_KW(self, state, inst): -+ narg = inst.arg -+ kw_names = state.pop() -+ args = list(reversed([state.pop() for _ in range(narg)])) -+ null_or_firstarg = state.pop() -+ callable = state.pop() -+ if not _is_null_temp_reg(null_or_firstarg): -+ args = [null_or_firstarg, *args] - -- if PYVERSION in ((3, 11), (3, 12)): -- if _is_null_temp_reg(state.peek(1)): -- state.pop() # pop NULL, it's not used -- elif PYVERSION in ((3, 9), (3, 10)): -- pass -- else: -- raise NotImplementedError(PYVERSION) -+ res = state.make_temp() -+ state.append(inst, func=callable, args=args, kw_names=kw_names, -+ res=res) -+ state.push(res) - -- res = state.make_temp() -- state.append(inst, func=func, vararg=vararg, varkwarg=varkwarg, res=res) -- state.push(res) -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ -+ if PYVERSION in ((3, 13),): -+ def op_CALL_FUNCTION_EX(self, state, inst): -+ # (func, unused, callargs, kwargs if (oparg & 1) -- result)) -+ if inst.arg & 1: -+ varkwarg = state.pop() -+ else: -+ varkwarg = None -+ -+ vararg = state.pop() -+ state.pop() # unused -+ func = state.pop() -+ -+ res = state.make_temp() -+ state.append(inst, func=func, vararg=vararg, varkwarg=varkwarg, -+ res=res) -+ state.push(res) -+ -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ -+ def op_CALL_FUNCTION_EX(self, state, inst): -+ if inst.arg & 1: -+ varkwarg = state.pop() -+ else: -+ varkwarg = None -+ vararg = state.pop() -+ func = state.pop() -+ -+ if PYVERSION in ((3, 11), (3, 12)): -+ if _is_null_temp_reg(state.peek(1)): -+ state.pop() # pop NULL, it's not used -+ elif PYVERSION in ((3, 9), (3, 10)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ -+ res = state.make_temp() -+ state.append(inst, func=func, vararg=vararg, varkwarg=varkwarg, -+ res=res) -+ state.push(res) -+ else: -+ raise NotImplementedError(PYVERSION) - - def _dup_topx(self, state, inst, count): - orig = [state.pop() for _ in range(count)] -@@ -1187,7 +1330,7 @@ class TraceRunner(object): - for val in duped: - state.push(val) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_CALL_INTRINSIC_1(self, state, inst): - # See https://github.com/python/cpython/blob/v3.12.0rc2/Include/ - # internal/pycore_intrinsics.h#L3-L17C36 -@@ -1404,7 +1547,7 @@ class TraceRunner(object): - pred=pred) - state.push(indval) - end = inst.get_jump_target() -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - # Changed in version 3.12: Up until 3.11 the iterator was - # popped when it was exhausted. Now this is handled using END_FOR - # op code. -@@ -1490,7 +1633,7 @@ class TraceRunner(object): - op_BINARY_XOR = _binaryop - - def op_MAKE_FUNCTION(self, state, inst, MAKE_CLOSURE=False): -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - # https://github.com/python/cpython/commit/2f180ce - # name set via co_qualname - name = None -@@ -1500,14 +1643,19 @@ class TraceRunner(object): - raise NotImplementedError(PYVERSION) - code = state.pop() - closure = annotations = kwdefaults = defaults = None -- if inst.arg & 0x8: -- closure = state.pop() -- if inst.arg & 0x4: -- annotations = state.pop() -- if inst.arg & 0x2: -- kwdefaults = state.pop() -- if inst.arg & 0x1: -- defaults = state.pop() -+ if PYVERSION in ((3, 13), ): -+ assert inst.arg is None -+ # SET_FUNCTION_ATTRIBUTE is responsible for setting -+ # closure, annotations, kwdefaults and defaults. -+ else: -+ if inst.arg & 0x8: -+ closure = state.pop() -+ if inst.arg & 0x4: -+ annotations = state.pop() -+ if inst.arg & 0x2: -+ kwdefaults = state.pop() -+ if inst.arg & 0x1: -+ defaults = state.pop() - res = state.make_temp() - state.append( - inst, -@@ -1521,6 +1669,27 @@ class TraceRunner(object): - ) - state.push(res) - -+ def op_SET_FUNCTION_ATTRIBUTE(self, state, inst): -+ assert PYVERSION in ((3, 13), ) -+ make_func_stack = state.pop() -+ data = state.pop() -+ if inst.arg == 0x1: -+ # 0x01 a tuple of default values for positional-only and -+ # positional-or-keyword parameters in positional order -+ state.set_function_attribute(make_func_stack, defaults=data) -+ elif inst.arg & 0x2: -+ # 0x02 a tuple of strings containing parameters’ annotations -+ state.set_function_attribute(make_func_stack, kwdefaults=data) -+ elif inst.arg & 0x4: -+ # 0x04 a tuple of strings containing parameters’ annotations -+ state.set_function_attribute(make_func_stack, annotations=data) -+ elif inst.arg == 0x8: -+ # 0x08 a tuple containing cells for free variables, making a closure -+ state.set_function_attribute(make_func_stack, closure=data) -+ else: -+ raise AssertionError("unreachable") -+ state.push(make_func_stack) -+ - def op_MAKE_CLOSURE(self, state, inst): - self.op_MAKE_FUNCTION(state, inst, MAKE_CLOSURE=True) - -@@ -1551,7 +1720,7 @@ class TraceRunner(object): - state.fork(pc=inst.next) - state.fork(pc=inst.get_jump_target()) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_RERAISE(self, state, inst): - # This isn't handled, but the state is set up anyway - exc = state.pop() -@@ -1576,7 +1745,7 @@ class TraceRunner(object): - # NOTE: Please see notes in `interpreter.py` surrounding the implementation - # of LOAD_METHOD and CALL_METHOD. - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - # LOAD_METHOD has become a pseudo-instruction in 3.12 - pass - elif PYVERSION in ((3, 11), ): -@@ -1828,9 +1997,14 @@ class _State(object): - return self.get_top_block('TRY') is not None - - def get_varname(self, inst): -+ """Get referenced variable name from the instruction's oparg -+ """ -+ return self.get_varname_by_arg(inst.arg) -+ -+ def get_varname_by_arg(self, oparg: int): - """Get referenced variable name from the oparg - """ -- return self._bytecode.co_varnames[inst.arg] -+ return self._bytecode.co_varnames[oparg] - - def terminate(self): - """Mark block as terminated -@@ -1852,7 +2026,7 @@ class _State(object): - stack.append(self.make_temp()) - # Handle changes on the blockstack - blockstack = list(self._blockstack) -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - # pop expired block in destination pc - while blockstack: - top = blockstack[-1] -@@ -1940,7 +2114,21 @@ class StatePy311(_State): - return self.make_temp(prefix="null$") - - --if PYVERSION >= (3, 11): -+class StatePy313(StatePy311): -+ def __init__(self, *args, **kwargs): -+ super().__init__(*args, **kwargs) -+ self._make_func_attrs = defaultdict(dict) -+ -+ def set_function_attribute(self, make_func_res, **kwargs): -+ self._make_func_attrs[make_func_res].update(kwargs) -+ -+ def get_function_attributes(self, make_func_res): -+ return self._make_func_attrs[make_func_res] -+ -+ -+if PYVERSION in ((3, 13), ): -+ State = StatePy313 -+elif PYVERSION in ((3, 11), (3, 12)): - State = StatePy311 - elif PYVERSION < (3, 11): - State = _State -@@ -1970,8 +2158,20 @@ AdaptBlockInfo = namedtuple( - - - def adapt_state_infos(state): -+ def process_function_attributes(inst_pair): -+ offset, data = inst_pair -+ inst = state._bytecode[offset] -+ if inst.opname == "MAKE_FUNCTION": -+ data.update(state.get_function_attributes(data['res'])) -+ return offset, data -+ if PYVERSION in ((3, 13), ): -+ insts = tuple(map(process_function_attributes, state.instructions)) -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ insts = tuple(state.instructions) -+ else: -+ raise NotImplementedError(PYVERSION) - return AdaptBlockInfo( -- insts=tuple(state.instructions), -+ insts=insts, - outgoing_phis=state.outgoing_phis, - blockstack=state.blockstack_initial, - active_try_block=state.find_initial_try_block(), -Index: numba-0.60.0/numba/core/controlflow.py -=================================================================== ---- numba-0.60.0.orig/numba/core/controlflow.py -+++ numba-0.60.0/numba/core/controlflow.py -@@ -954,7 +954,7 @@ class ControlFlowAnalysis(object): - self._curblock.terminating = True - self._force_new_block = True - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_RETURN_CONST(self, inst): - self._curblock.terminating = True - self._force_new_block = True -Index: numba-0.60.0/numba/core/interpreter.py -=================================================================== ---- numba-0.60.0.orig/numba/core/interpreter.py -+++ numba-0.60.0/numba/core/interpreter.py -@@ -6,7 +6,11 @@ import logging - import textwrap - - from numba.core import errors, ir, config --from numba.core.errors import NotDefinedError, UnsupportedError, error_extras -+from numba.core.errors import ( -+ NotDefinedError, -+ UnsupportedBytecodeError, -+ error_extras, -+) - from numba.core.ir_utils import get_definition, guard - from numba.core.utils import (PYVERSION, BINOPS_TO_OPERATORS, - INPLACE_BINOPS_TO_OPERATORS,) -@@ -15,7 +19,7 @@ from numba.core.unsafe import eh - from numba.cpython.unsafe.tuple import unpack_single_tuple - - --if PYVERSION in ((3, 12), ): -+if PYVERSION in ((3, 12), (3, 13)): - # Operands for CALL_INTRINSIC_1 - from numba.core.byteflow import CALL_INTRINSIC_1_Operand as ci1op - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): -@@ -108,7 +112,7 @@ def _remove_assignment_definition(old_bo - func_ir._definitions[lhs].remove(rhs) - already_deleted_defs[lhs].add(rhs) - elif rhs not in already_deleted_defs[lhs]: -- raise UnsupportedError( -+ raise UnsupportedBytecodeError( - "Inconsistency found in the definitions while executing" - " a peephole optimization. This suggests an internal" - " error or inconsistency elsewhere in the compiler." -@@ -211,7 +215,7 @@ def _call_function_ex_replace_kws_large( - ): - # We cannot handle this format so raise the - # original error message. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - key_var_name = const_stmt.target.name - key_val = const_stmt.value.value - search_start += 1 -@@ -257,7 +261,7 @@ def _call_function_ex_replace_kws_large( - ): - # We cannot handle this format so raise the - # original error message. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - setitem_stmt = old_body[search_start + 1] - if not ( - isinstance(setitem_stmt, ir.Assign) -@@ -277,7 +281,7 @@ def _call_function_ex_replace_kws_large( - # getattr. If for some reason this doesn't match the code - # format, we raise the original error message. This check - # is meant as a precaution. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - arg_var = setitem_stmt.value.args[1] - # Append the (key, value) pair. - kws.append((key_val, arg_var)) -@@ -421,7 +425,7 @@ def _call_function_ex_replace_args_large - and concat_stmt.value.fn == operator.add - ): - # We cannot handle this format. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - lhs_name = concat_stmt.value.lhs.name - rhs_name = concat_stmt.value.rhs.name - # The previous statement should be a -@@ -439,7 +443,7 @@ def _call_function_ex_replace_args_large - and len(arg_tuple_stmt.value.items) == 1 - ): - # We cannot handle this format. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - if arg_tuple_stmt.target.name == lhs_name: - # The tuple should always be generated on the RHS. - raise AssertionError("unreachable") -@@ -447,7 +451,7 @@ def _call_function_ex_replace_args_large - target_name = lhs_name - else: - # We cannot handle this format. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - total_args.append( - arg_tuple_stmt.value.items[0] - ) -@@ -497,7 +501,7 @@ def _call_function_ex_replace_args_large - # If we reached the start we never found the build_tuple. - # We cannot handle this format so raise the - # original error message. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - # Reverse the arguments so we get the correct order. - return total_args[::-1] - -@@ -586,7 +590,7 @@ def peep_hole_call_function_ex_to_call_f - # If we couldn't find where the kwargs are created - # then it should be a normal **kwargs call - # so we produce an unsupported message. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - # Determine the kws - if keyword_def.value.items: - # n_kws <= 15 case. -@@ -638,7 +642,7 @@ def peep_hole_call_function_ex_to_call_f - if args: - # If we have vararg then args is expected to - # be an empty list. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - vararg_loc = start_search - args_def = None - found = False -@@ -654,7 +658,7 @@ def peep_hole_call_function_ex_to_call_f - if not found: - # If we couldn't find where the args are created - # then we can't handle this format. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - if ( - isinstance(args_def.value, ir.Expr) - and args_def.value.op == "build_tuple" -@@ -683,7 +687,7 @@ def peep_hole_call_function_ex_to_call_f - # If there is a call with vararg we need to check - # if the list -> tuple conversion failed and if so - # throw an error. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - else: - # Here the IR is an initial empty build_tuple. - # Then for each arg, a new tuple with a single -@@ -747,7 +751,7 @@ def peep_hole_call_function_ex_to_call_f - # exception. - expr = func_ir._definitions[vararg_name][0] - if isinstance(expr, ir.Expr) and expr.op == "list_to_tuple": -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - - new_body.append(stmt) - # Replace the block body if we changed the IR -@@ -1197,7 +1201,7 @@ def peep_hole_fuse_dict_add_updates(func - else: - # If we cannot remove _update_from_bytecode - # Then raise an error for the user. -- raise UnsupportedError(errmsg) -+ raise UnsupportedBytecodeError(errmsg) - - # Check if we need to drop any maps from being tracked. - # Skip the setitem/_update_from_bytecode getattr that -@@ -1385,7 +1389,7 @@ class Interpreter(object): - max(inst_blocks.body)) - self.last_active_offset = last_active_offset - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - self.active_exception_entries = tuple( - [entry for entry in self.bytecode.exception_entries - if entry.start < self.last_active_offset]) -@@ -1401,7 +1405,7 @@ class Interpreter(object): - # Interpret loop - for inst, kws in self._iter_inst(): - self._dispatch(inst, kws) -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - # Insert end of try markers - self._end_try_blocks() - elif PYVERSION in ((3, 9), (3, 10)): -@@ -1418,12 +1422,12 @@ class Interpreter(object): - # post process the IR to rewrite opcodes/byte sequences that are too - # involved to risk handling as part of direct interpretation - peepholes = [] -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - peepholes.append(peep_hole_split_at_pop_block) -- if PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12)): -+ if PYVERSION in ((3, 9), (3, 10), (3, 11), (3, 12), (3, 13)): - peepholes.append(peep_hole_list_to_tuple) - peepholes.append(peep_hole_delete_with_exit) -- if PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ if PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)): - # peep_hole_call_function_ex_to_call_function_kw - # depends on peep_hole_list_to_tuple converting - # any large number of arguments from a list to a -@@ -1456,7 +1460,7 @@ class Interpreter(object): - - See also: _insert_try_block_end - """ -- assert PYVERSION in ((3, 11), (3, 12)) -+ assert PYVERSION in ((3, 11), (3, 12), (3, 13)) - graph = self.cfa.graph - for offset, block in self.blocks.items(): - # Get current blockstack -@@ -1507,7 +1511,7 @@ class Interpreter(object): - first = uservar[0] - loc = self.current_scope.get(first).loc - msg = "Exception object cannot be stored into variable ({})." -- raise errors.UnsupportedError(msg.format(first), loc=loc) -+ raise errors.UnsupportedBytecodeError(msg.format(first), loc=loc) - - def init_first_block(self): - # Define variables receiving the function arguments -@@ -1564,7 +1568,7 @@ class Interpreter(object): - self.dfainfo = self.dfa.infos[self.current_block_offset] - self.assigner = Assigner() - # Check out-of-scope syntactic-block -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - # This is recreating pre-3.11 code structure - while self.syntax_blocks: - if offset >= self.syntax_blocks[-1].exit: -@@ -1735,7 +1739,7 @@ class Interpreter(object): - val = self.get(varname) - except ir.NotDefinedError: - # Hack to make sure exception variables are defined -- assert PYVERSION in ((3, 11), (3, 12)), \ -+ assert PYVERSION in ((3, 11), (3, 12), (3, 13)), \ - "unexpected missing definition" - val = ir.Const(value=None, loc=self.loc) - stmt = ir.Assign(value=val, target=target, -@@ -1795,7 +1799,7 @@ class Interpreter(object): - if self._DEBUG_PRINT: - print(inst) - assert self.current_block is not None -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - if self.syntax_blocks: - top = self.syntax_blocks[-1] - if isinstance(top, ir.With) : -@@ -1825,6 +1829,9 @@ class Interpreter(object): - if not config.FULL_TRACEBACKS: - raise err from None - else: -+ m = f"handling op: {inst} | offset: {inst.offset}" -+ err.add_context(m) -+ err.add_context(self.bytecode.dump()) - raise err - - # --- Scope operations --- -@@ -1921,6 +1928,10 @@ class Interpreter(object): - loc=self.loc) - self.store(expr, st) - -+ def op_FORMAT_SIMPLE(self, inst, value, res, strvar): -+ # Same as FORMAT_VALUE -+ return self.op_FORMAT_VALUE(inst, value, res, strvar) -+ - def op_FORMAT_VALUE(self, inst, value, res, strvar): - """ - FORMAT_VALUE(flags): flags argument specifies format spec which is not -@@ -1971,7 +1982,7 @@ class Interpreter(object): - (), loc=self.loc) - self.store(value=sliceinst, name=res) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_BINARY_SLICE(self, inst, start, end, container, res, slicevar, - temp_res): - start = self.get(start) -@@ -1990,7 +2001,7 @@ class Interpreter(object): - else: - raise NotImplementedError(PYVERSION) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_STORE_SLICE(self, inst, start, end, container, value, res, - slicevar): - start = self.get(start) -@@ -2218,11 +2229,58 @@ class Interpreter(object): - stmt = ir.DelItem(base, self.get(indexvar), loc=self.loc) - self.current_block.append(stmt) - -- def op_LOAD_FAST(self, inst, res): -+ def _op_LOAD_FAST(self, inst, res): - srcname = self.code_locals[inst.arg] - self.store(value=self.get(srcname), name=res) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 13), ): -+ def op_LOAD_FAST(self, inst, res, as_load_deref=False): -+ if as_load_deref: -+ self.op_LOAD_DEREF(inst, res) -+ else: -+ self._op_LOAD_FAST(inst, res) -+ -+ else: -+ op_LOAD_FAST = _op_LOAD_FAST -+ -+ if PYVERSION in ((3, 13),): -+ def op_LOAD_FAST_LOAD_FAST(self, inst, res1, res2): -+ oparg = inst.arg -+ oparg1 = oparg >> 4 -+ oparg2 = oparg & 15 -+ src1 = self.get(self.code_locals[oparg1]) -+ src2 = self.get(self.code_locals[oparg2]) -+ self.store(value=src1, name=res1) -+ self.store(value=src2, name=res2) -+ -+ def op_STORE_FAST_LOAD_FAST(self, inst, store_value, load_res): -+ oparg = inst.arg -+ oparg1 = oparg >> 4 -+ oparg2 = oparg & 15 -+ -+ dstname = self.code_locals[oparg1] -+ dst_value = self.get(store_value) -+ self.store(value=dst_value, name=dstname) -+ -+ src_value = self.get(self.code_locals[oparg2]) -+ self.store(value=src_value, name=load_res) -+ -+ def op_STORE_FAST_STORE_FAST(self, inst, value1, value2): -+ oparg = inst.arg -+ oparg1 = oparg >> 4 -+ oparg2 = oparg & 15 -+ -+ dstname = self.code_locals[oparg1] -+ self.store(value=self.get(value1), name=dstname) -+ dstname = self.code_locals[oparg2] -+ self.store(value=self.get(value2), name=dstname) -+ -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ -+ if PYVERSION in ((3, 12), (3, 13)): - op_LOAD_FAST_CHECK = op_LOAD_FAST - - def op_LOAD_FAST_AND_CLEAR(self, inst, res): -@@ -2269,7 +2327,7 @@ class Interpreter(object): - - def op_LOAD_ATTR(self, inst, item, res): - item = self.get(item) -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - attr = self.code_names[inst.arg >> 1] - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): - attr = self.code_names[inst.arg] -@@ -2300,7 +2358,7 @@ class Interpreter(object): - const = ir.Const(value, loc=self.loc) - self.store(const, res) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_LOAD_GLOBAL(self, inst, idx, res): - name = self.code_names[idx] - value = self.get_global_value(name) -@@ -2318,11 +2376,15 @@ class Interpreter(object): - def op_COPY_FREE_VARS(self, inst): - pass - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_LOAD_DEREF(self, inst, res): - name = self.func_id.func.__code__._varname_from_oparg(inst.arg) - if name in self.code_cellvars: -- gl = self.get(name) -+ try: -+ gl = self.get(name) -+ except NotDefinedError: -+ msg = "Unsupported use of cell variable encountered" -+ raise NotImplementedError(msg) - elif name in self.code_freevars: - idx = self.code_freevars.index(name) - value = self.get_closure_value(idx) -@@ -2343,11 +2405,11 @@ class Interpreter(object): - else: - raise NotImplementedError(PYVERSION) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_MAKE_CELL(self, inst): - pass # ignored bytecode - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_STORE_DEREF(self, inst, value): - name = self.func_id.func.__code__._varname_from_oparg(inst.arg) - value = self.get(value) -@@ -2387,7 +2449,7 @@ class Interpreter(object): - - def op_BEFORE_WITH(self, inst, contextmanager, exitfn, end): - assert self.blocks[inst.offset] is self.current_block -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - # Python 3.12 hack for handling nested with blocks - if end > self.last_active_offset: - # Use exception entries to figure out end of syntax block -@@ -2437,6 +2499,7 @@ class Interpreter(object): - func = self.get(func) - args = [self.get(x) for x in args] - if kw_names is not None: -+ assert PYVERSION < (3, 13) - names = self.code_consts[kw_names] - kwargs = list(zip(names, args[-len(names):])) - args = args[:-len(names)] -@@ -2445,6 +2508,19 @@ class Interpreter(object): - expr = ir.Expr.call(func, args, kwargs, loc=self.loc) - self.store(expr, res) - -+ if PYVERSION in ((3, 13),): -+ def op_CALL_KW(self, inst, func, args, kw_names, res): -+ func = self.get(func) -+ args = [self.get(x) for x in args] -+ consti = int(kw_names.rsplit('.', 2)[-1]) -+ names = self.code_consts[consti] -+ kwargs = list(zip(names, args[-len(names):])) -+ args = args[:-len(names)] -+ expr = ir.Expr.call(func, args, kwargs, loc=self.loc) -+ self.store(expr, res) -+ else: -+ assert PYVERSION < (3, 13) -+ - def op_CALL_FUNCTION(self, inst, func, args, res): - func = self.get(func) - args = [self.get(x) for x in args] -@@ -2878,6 +2954,8 @@ class Interpreter(object): - jmp = ir.Jump(inst.get_jump_target(), loc=self.loc) - self.current_block.append(jmp) - -+ op_JUMP_BACKWARD_NO_INTERRUPT = op_JUMP_BACKWARD -+ - def op_POP_BLOCK(self, inst, kind=None): - if kind is None: - self.syntax_blocks.pop() -@@ -2892,7 +2970,7 @@ class Interpreter(object): - ret = ir.Return(self.get(castval), loc=self.loc) - self.current_block.append(ret) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_RETURN_CONST(self, inst, retval, castval): - value = self.code_consts[inst.arg] - const = ir.Const(value, loc=self.loc) -@@ -2905,8 +2983,20 @@ class Interpreter(object): - else: - raise NotImplementedError(PYVERSION) - -+ if PYVERSION in ((3, 13),): -+ def op_TO_BOOL(self, inst, val, res): -+ self.store(self.get(val), res) # TODO: just a lazy hack -+ -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ pass -+ else: -+ raise NotImplementedError(PYVERSION) -+ - def op_COMPARE_OP(self, inst, lhs, rhs, res): -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 13),): -+ op = dis.cmp_op[inst.arg >> 5] -+ # TODO: fifth lowest bit now indicates a forced version to bool. -+ elif PYVERSION in ((3, 12),): - op = dis.cmp_op[inst.arg >> 4] - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): - op = dis.cmp_op[inst.arg] -@@ -3024,7 +3114,7 @@ class Interpreter(object): - def op_POP_JUMP_FORWARD_IF_NOT_NONE(self, inst, pred): - self._jump_if_none(inst, pred, False) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_POP_JUMP_IF_NONE(self, inst, pred): - self._jump_if_none(inst, pred, True) - -@@ -3152,7 +3242,7 @@ class Interpreter(object): - "Probably caused by complex control-flow constructs; " - "e.g. try-except" - ) -- raise errors.UnsupportedError(msg, loc=self.loc) -+ raise errors.UnsupportedBytecodeError(msg, loc=self.loc) - fcode = assume_code_const.value - if name: - name = self.get(name) -@@ -3166,14 +3256,14 @@ class Interpreter(object): - self.op_MAKE_FUNCTION(inst, name, code, closure, annotations, - kwdefaults, defaults, res) - -- if PYVERSION in ((3, 11), (3, 12)): -+ if PYVERSION in ((3, 11), (3, 12), (3, 13)): - def op_LOAD_CLOSURE(self, inst, res): - name = self.func_id.func.__code__._varname_from_oparg(inst.arg) - if name in self.code_cellvars: - try: - gl = self.get(name) - except NotDefinedError: -- msg = "Unsupported use of op_LOAD_CLOSURE encountered" -+ msg = "Unsupported use of cell variable encountered" - raise NotImplementedError(msg) - elif name in self.code_freevars: - idx = self.code_freevars.index(name) -@@ -3191,7 +3281,7 @@ class Interpreter(object): - try: - gl = self.get(name) - except NotDefinedError: -- msg = "Unsupported use of op_LOAD_CLOSURE encountered" -+ msg = "Unsupported use of cell variable encountered" - raise NotImplementedError(msg) - else: - idx = inst.arg - n_cellvars -@@ -3228,7 +3318,7 @@ class Interpreter(object): - "op_LIST_EXTEND at the start of a block.\n\nThis could be " - "due to the use of a branch in a tuple unpacking statement.") - if not self.current_block.body: -- raise errors.UnsupportedError(msg) -+ raise errors.UnsupportedBytecodeError(msg) - - # is last emitted statement a build_tuple? - stmt = self.current_block.body[-1] -@@ -3258,7 +3348,7 @@ class Interpreter(object): - ok = False - break - if ok and build_empty_list is None: -- raise errors.UnsupportedError(msg) -+ raise errors.UnsupportedBytecodeError(msg) - if ok: - stmts = self.current_block.body - build_tuple_asgn = self.current_block.body[-1] -@@ -3304,7 +3394,7 @@ class Interpreter(object): - def op_CALL_METHOD(self, *args, **kws): - self.op_CALL_FUNCTION(*args, **kws) - -- if PYVERSION in ((3, 12), ): -+ if PYVERSION in ((3, 12), (3, 13)): - def op_CALL_INTRINSIC_1(self, inst, operand, **kwargs): - if operand == ci1op.INTRINSIC_STOPITERATION_ERROR: - stmt = ir.StaticRaise(INTRINSIC_STOPITERATION_ERROR, (), -@@ -3325,7 +3415,7 @@ class Interpreter(object): - raise NotImplementedError(PYVERSION) - - --if PYVERSION in ((3, 12), ): -+if PYVERSION in ((3, 12), (3, 13)): - class INTRINSIC_STOPITERATION_ERROR(AssertionError): - pass - elif PYVERSION in ((3, 9), (3, 10), (3, 11)): -Index: numba-0.60.0/numba/cpython/unicode.py -=================================================================== ---- numba-0.60.0.orig/numba/cpython/unicode.py -+++ numba-0.60.0/numba/cpython/unicode.py -@@ -349,7 +349,7 @@ def _set_code_point(a, i, ch): - "Unexpected unicode representation in _set_code_point") - - --if PYVERSION in ((3, 12),): -+if PYVERSION in ((3, 12), (3, 13)): - @register_jitable - def _pick_kind(kind1, kind2): - if kind1 == PY_UNICODE_1BYTE_KIND: -@@ -393,7 +393,7 @@ def _pick_ascii(is_ascii1, is_ascii2): - return types.uint32(0) - - --if PYVERSION in ((3, 12),): -+if PYVERSION in ((3, 12), (3, 13)): - @register_jitable - def _kind_to_byte_width(kind): - if kind == PY_UNICODE_1BYTE_KIND: -@@ -2047,7 +2047,7 @@ def _is_upper(is_lower, is_upper, is_tit - def impl(a): - l = len(a) - if l == 1: -- return is_upper(_get_code_point(a, 0)) -+ return is_upper(_get_code_point(a, 0)) != 0 - if l == 0: - return False - cased = False -Index: numba-0.60.0/numba/experimental/jitclass/base.py -=================================================================== ---- numba-0.60.0.orig/numba/experimental/jitclass/base.py -+++ numba-0.60.0/numba/experimental/jitclass/base.py -@@ -282,6 +282,9 @@ def _drop_ignored_attrs(dct): - drop = set(['__weakref__', - '__module__', - '__dict__']) -+ if utils.PYVERSION == (3, 13): -+ # new in python 3.13 -+ drop |= set(['__firstlineno__', '__static_attributes__']) - - if '__annotations__' in dct: - drop.add('__annotations__') -@@ -300,7 +303,7 @@ def _drop_ignored_attrs(dct): - drop.add('__hash__') - - for k in drop: -- del dct[k] -+ dct.pop(k) - - - class ClassBuilder(object): -Index: numba-0.60.0/numba/core/compiler.py -=================================================================== ---- numba-0.60.0.orig/numba/core/compiler.py -+++ numba-0.60.0/numba/core/compiler.py -@@ -476,10 +476,7 @@ class CompilerBase(object): - res = e.result - break - except Exception as e: -- if (utils.use_new_style_errors() and not -- isinstance(e, errors.NumbaError)): -- raise e -- -+ utils.handle_new_style_errors(e) - self.state.status.fail_reason = e - if is_final_pipeline: - raise e -Index: numba-0.60.0/numba/core/compiler_machinery.py -=================================================================== ---- numba-0.60.0.orig/numba/core/compiler_machinery.py -+++ numba-0.60.0/numba/core/compiler_machinery.py -@@ -304,7 +304,8 @@ class PassManager(object): - args=str(internal_state.args), - return_type=str(internal_state.return_type), - ) -- with ev.trigger_event("numba:run_pass", data=ev_details): -+ errctx = errors.new_error_context(f"Pass {pss.name()}") -+ with ev.trigger_event("numba:run_pass", data=ev_details), errctx: - with SimpleTimer() as init_time: - mutated |= check(pss.run_initialization, internal_state) - with SimpleTimer() as pass_time: -@@ -359,9 +360,7 @@ class PassManager(object): - except _EarlyPipelineCompletion as e: - raise e - except Exception as e: -- if (utils.use_new_style_errors() and not -- isinstance(e, errors.NumbaError)): -- raise e -+ utils.handle_new_style_errors(e) - msg = "Failed in %s mode pipeline (step: %s)" % \ - (self.pipeline_name, pass_desc) - patched_exception = self._patch_error(msg, e) -Index: numba-0.60.0/numba/core/errors.py -=================================================================== ---- numba-0.60.0.orig/numba/core/errors.py -+++ numba-0.60.0/numba/core/errors.py -@@ -532,7 +532,6 @@ class WarningsFixer(object): - - - class NumbaError(Exception): -- - def __init__(self, msg, loc=None, highlighting=True): - self.msg = msg - self.loc = loc -@@ -578,7 +577,13 @@ class UnsupportedError(NumbaError): - """ - Numba does not have an implementation for this functionality. - """ -- pass -+ -+ -+class UnsupportedBytecodeError(Exception): -+ """Unsupported bytecode is non-recoverable -+ """ -+ def __init__(self, msg, loc=None): -+ super().__init__(f"{msg}. Raised from {loc}") - - - class UnsupportedRewriteError(UnsupportedError): -Index: numba-0.60.0/numba/core/types/functions.py -=================================================================== ---- numba-0.60.0.orig/numba/core/types/functions.py -+++ numba-0.60.0/numba/core/types/functions.py -@@ -307,12 +307,9 @@ class BaseFunction(Callable): - for k, v in kws.items()} - sig = temp.apply(nolitargs, nolitkws) - except Exception as e: -- if (utils.use_new_style_errors() and not -- isinstance(e, errors.NumbaError)): -- raise e -- else: -- sig = None -- failures.add_error(temp, False, e, uselit) -+ utils.handle_new_style_errors(e) -+ sig = None -+ failures.add_error(temp, False, e, uselit) - else: - if sig is not None: - self._impl_keys[sig.args] = temp.get_impl_key(sig) -Index: numba-0.60.0/numba/core/utils.py -=================================================================== ---- numba-0.60.0.orig/numba/core/utils.py -+++ numba-0.60.0/numba/core/utils.py -@@ -230,6 +230,17 @@ def use_old_style_errors(): - return res - - -+def handle_new_style_errors(e): -+ """Handle new_style error by raising the exception immediately if they are -+ non-recoverable. -+ """ -+ from numba.core import errors -+ -+ if use_new_style_errors(): -+ if not isinstance(e, errors.NumbaError): -+ raise e -+ -+ - class ThreadLocalStack: - """A TLS stack container. - -Index: numba-0.60.0/numba/stencils/stencil.py -=================================================================== ---- numba-0.60.0.orig/numba/stencils/stencil.py -+++ numba-0.60.0/numba/stencils/stencil.py -@@ -402,8 +402,9 @@ class StencilFunc(object): - sig = signature(real_ret, *argtys_extra) - dummy_text = ("def __numba_dummy_stencil({}{}):\n pass\n".format( - ",".join(self.kernel_ir.arg_names), sig_extra)) -- exec(dummy_text) in globals(), locals() -- dummy_func = eval("__numba_dummy_stencil") -+ dct = {} -+ exec(dummy_text, dct) -+ dummy_func = dct["__numba_dummy_stencil"] - sig = sig.replace(pysig=utils.pysignature(dummy_func)) - self._targetctx.insert_func_defn([(self._lower_me, self, argtys_extra)]) - self._type_cache[argtys_extra] = (sig, result, typemap, calltypes) -@@ -659,8 +660,10 @@ class StencilFunc(object): - print(func_text) - - # Force the new stencil function into existence. -- exec(func_text) in globals(), locals() -- stencil_func = eval(stencil_func_name) -+ dct = {} -+ dct.update(globals()) -+ exec(func_text, dct) -+ stencil_func = dct[stencil_func_name] - if sigret is not None: - pysig = utils.pysignature(stencil_func) - sigret.pysig = pysig -Index: numba-0.60.0/numba/tests/test_debug.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_debug.py -+++ numba-0.60.0/numba/tests/test_debug.py -@@ -73,7 +73,7 @@ class DebugTestBase(TestCase): - self.assert_fails(check_meth, out) - - def _check_dump_bytecode(self, out): -- if utils.PYVERSION in ((3, 11), (3, 12)): -+ if utils.PYVERSION in ((3, 11), (3, 12), (3, 13)): - self.assertIn('BINARY_OP', out) - elif utils.PYVERSION in ((3, 9), (3, 10)): - self.assertIn('BINARY_ADD', out) -Index: numba-0.60.0/numba/tests/test_ir_inlining.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_ir_inlining.py -+++ numba-0.60.0/numba/tests/test_ir_inlining.py -@@ -444,7 +444,7 @@ class TestFunctionInlining(MemoryLeakMix - return bar(z + 2) - - # block count changes with Python version due to bytecode differences. -- if utils.PYVERSION in ((3, 12), ): -+ if utils.PYVERSION in ((3, 12), (3, 13)): - bc = 39 - elif utils.PYVERSION in ((3, 10), (3, 11)): - bc = 35 -Index: numba-0.60.0/numba/tests/test_closure.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_closure.py -+++ numba-0.60.0/numba/tests/test_closure.py -@@ -400,13 +400,13 @@ class TestInlinedClosure(TestCase): - with self.assertRaises(NotImplementedError) as raises: - cfunc = jit(nopython=True)(outer3) - cfunc(var) -- msg = "Unsupported use of op_LOAD_CLOSURE encountered" -+ msg = "Unsupported use of cell variable encountered" - self.assertIn(msg, str(raises.exception)) - - with self.assertRaises(NotImplementedError) as raises: - cfunc = jit(nopython=True)(outer4) - cfunc(var) -- msg = "Unsupported use of op_LOAD_CLOSURE encountered" -+ msg = "Unsupported use of cell variable encountered" - self.assertIn(msg, str(raises.exception)) - - with self.assertRaises(TypingError) as raises: -Index: numba-0.60.0/numba/core/inline_closurecall.py -=================================================================== ---- numba-0.60.0.orig/numba/core/inline_closurecall.py -+++ numba-0.60.0/numba/core/inline_closurecall.py -@@ -95,7 +95,7 @@ class InlineClosureCallPass(object): - modified = False - work_list = list(self.func_ir.blocks.items()) - debug_print = _make_debug_print("InlineClosureCallPass") -- debug_print("START") -+ debug_print(f"START {self.func_ir.func_id.func_qualname}") - while work_list: - _label, block = work_list.pop() - for i, instr in enumerate(block.body): -Index: numba-0.60.0/numba/pycc/modulemixin.c -=================================================================== ---- numba-0.60.0.orig/numba/pycc/modulemixin.c -+++ numba-0.60.0/numba/pycc/modulemixin.c -@@ -23,6 +23,12 @@ - #include "../core/runtime/nrt.h" - #endif - -+#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION >= 12) -+ #define Py_BUILD_CORE 1 -+ #include "internal/pycore_pyhash.h" -+ #undef Py_BUILD_CORE -+#endif -+ - /* Defines hashsecret variables (see issue #6386) */ - int64_t _numba_hashsecret_siphash_k0; - int64_t _numba_hashsecret_siphash_k1; -Index: numba-0.60.0/numba/tests/test_operators.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_operators.py -+++ numba-0.60.0/numba/tests/test_operators.py -@@ -768,7 +768,7 @@ class TestOperators(TestCase): - # error message depends on Python version. - if utils.PYVERSION in ((3, 9),): - msg = "can't mod complex numbers" -- elif utils.PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ elif utils.PYVERSION in ((3, 10), (3, 11), (3, 12), (3, 13)): - msg = "unsupported operand type(s) for %" - else: - raise NotImplementedError(utils.PYVERSION) -Index: numba-0.60.0/numba/tests/test_parfors.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_parfors.py -+++ numba-0.60.0/numba/tests/test_parfors.py -@@ -3550,7 +3550,7 @@ class TestPrangeBase(TestParforsBase): - prange_names.append('prange') - prange_names = tuple(prange_names) - prange_idx = len(prange_names) - 1 -- if utils.PYVERSION in ((3, 11), (3, 12)): -+ if utils.PYVERSION in ((3, 11), (3, 12), (3, 13)): - # this is the inverse of _fix_LOAD_GLOBAL_arg - prange_idx = 1 + (prange_idx << 1) - elif utils.PYVERSION in ((3, 9), (3, 10)): -Index: numba-0.60.0/numba/tests/support.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/support.py -+++ numba-0.60.0/numba/tests/support.py -@@ -128,6 +128,12 @@ def expected_failure_np2(fn): - else: - return fn - -+def expected_failure_py313(fn): -+ if utils.PYVERSION == (3, 13): -+ return unittest.expectedFailure(fn) -+ else: -+ return fn -+ - _msg = "SciPy needed for test" - skip_unless_scipy = unittest.skipIf(scipy is None, _msg) - -Index: numba-0.60.0/numba/tests/test_np_functions.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_np_functions.py -+++ numba-0.60.0/numba/tests/test_np_functions.py -@@ -6192,8 +6192,9 @@ def foo(): - tystr = ty.__name__ - basestr = basefunc.__name__ - funcstr = self.template % (tystr, basestr) -- eval(compile(funcstr, '', 'exec')) -- return locals()['foo'] -+ dct = {} -+ exec(compile(funcstr, '', 'exec'), globals(), dct) -+ return dct['foo'] - - @unittest.skipIf(numpy_version >= (1, 24), "NumPy < 1.24 required") - def test_MachAr(self): -Index: numba-0.60.0/numba/tests/test_unicode.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_unicode.py -+++ numba-0.60.0/numba/tests/test_unicode.py -@@ -6,10 +6,12 @@ from numba import njit, typeof - from numba.core import types - import unittest - from numba.tests.support import (TestCase, no_pyobj_flags, MemoryLeakMixin) --from numba.core.errors import TypingError, UnsupportedError -+from numba.core.errors import (TypingError, UnsupportedError, -+ UnsupportedBytecodeError) - from numba.cpython.unicode import _MAX_UNICODE - from numba.core.types.functions import _header_lead - from numba.extending import overload -+from numba.core.utils import PYVERSION - - - def isascii(s): -@@ -2697,10 +2699,17 @@ class TestUnicodeAuxillary(BaseTest): - self.assertEqual(got, expected) - - # check error when format spec provided -- with self.assertRaises(UnsupportedError) as raises: -+ unsupported_errors = (UnsupportedError, UnsupportedBytecodeError) -+ with self.assertRaises(unsupported_errors) as raises: - njit(impl4)(["A", "B"]) -- msg = "format spec in f-strings not supported yet" -- self.assertIn(msg, str(raises.exception)) -+ if PYVERSION in ((3, 13),): -+ msg = "Use of unsupported opcode (FORMAT_WITH_SPEC)" -+ self.assertIn(msg, str(raises.exception)) -+ elif PYVERSION in ((3, 10), (3, 11), (3, 12)): -+ msg = "format spec in f-strings not supported yet" -+ self.assertIn(msg, str(raises.exception)) -+ else: -+ raise NotImplementedError(PYVERSION) - self.assertEqual(impl5(), njit(impl5)()) - - -Index: numba-0.60.0/numba/core/ir.py -=================================================================== ---- numba-0.60.0.orig/numba/core/ir.py -+++ numba-0.60.0/numba/core/ir.py -@@ -90,9 +90,12 @@ class Loc(object): - - def get_lines(self): - if self.lines is None: -- -- self.lines = linecache.getlines(self._get_path()) -- -+ path = self._get_path() -+ # Avoid reading from dynamic string. They are most likely -+ # overridden. Problem started with Python 3.13. "" seems -+ # to be something from multiprocessing. -+ lns = [] if path == "" else linecache.getlines(path) -+ self.lines = lns - return self.lines - - def _get_path(self): -@@ -1496,7 +1499,7 @@ class FunctionIR(object): - self.block_entry_vars = {} - - def derive(self, blocks, arg_count=None, arg_names=None, -- force_non_generator=False): -+ force_non_generator=False, loc=None): - """ - Derive a new function IR from this one, using the given blocks, - and possibly modifying the argument count and generator flag. -@@ -1507,7 +1510,7 @@ class FunctionIR(object): - - new_ir = copy.copy(self) - new_ir.blocks = blocks -- new_ir.loc = firstblock.loc -+ new_ir.loc = firstblock.loc if loc is None else loc - if force_non_generator: - new_ir.is_generator = False - if arg_count is not None: -Index: numba-0.60.0/numba/core/transforms.py -=================================================================== ---- numba-0.60.0.orig/numba/core/transforms.py -+++ numba-0.60.0/numba/core/transforms.py -@@ -191,12 +191,20 @@ def _loop_lift_modify_blocks(func_ir, lo - loopblocks = dict((k, blocks[k].copy()) for k in loopblockkeys) - # Modify the loop blocks - _loop_lift_prepare_loop_func(loopinfo, loopblocks) -- -+ # Since Python 3.13, [END_FOR, POP_TOP] sequence becomes the start of the -+ # block causing the block to have line number of the start of previous loop. -+ # Fix this using the loc of the first getiter. -+ getiter_exprs = [] -+ for blk in loopblocks.values(): -+ getiter_exprs.extend(blk.find_exprs(op="getiter")) -+ first_getiter = min(getiter_exprs, key=lambda x: x.loc.line) -+ loop_loc = first_getiter.loc - # Create a new IR for the lifted loop - lifted_ir = func_ir.derive(blocks=loopblocks, - arg_names=tuple(loopinfo.inputs), - arg_count=len(loopinfo.inputs), -- force_non_generator=True) -+ force_non_generator=True, -+ loc=loop_loc) - liftedloop = LiftedLoop(lifted_ir, - typingctx, targetctx, flags, locals) - -Index: numba-0.60.0/numba/tests/test_exceptions.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_exceptions.py -+++ numba-0.60.0/numba/tests/test_exceptions.py -@@ -6,6 +6,7 @@ from numba import jit, njit - from numba.core import types, errors, utils - from numba.tests.support import (TestCase, expected_failure_py311, - expected_failure_py312, -+ expected_failure_py313, - ) - import unittest - -@@ -440,6 +441,7 @@ class TestRaising(TestCase): - - @expected_failure_py311 - @expected_failure_py312 -+ @expected_failure_py313 - def test_dynamic_raise(self): - - @njit -Index: numba-0.60.0/numba/tests/test_try_except.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_try_except.py -+++ numba-0.60.0/numba/tests/test_try_except.py -@@ -8,12 +8,13 @@ from numba import njit, typed, objmode, - from numba.core.utils import PYVERSION - from numba.core import ir_utils, ir - from numba.core.errors import ( -- UnsupportedError, CompilerError, NumbaPerformanceWarning, TypingError, -+ CompilerError, NumbaPerformanceWarning, TypingError, -+ UnsupportedBytecodeError, - ) - from numba.tests.support import ( - TestCase, unittest, captured_stdout, MemoryLeakMixin, - skip_parfors_unsupported, skip_unless_scipy, expected_failure_py311, -- expected_failure_py312 -+ expected_failure_py312, expected_failure_py313, - ) - - -@@ -372,7 +373,7 @@ class TestTryBareExcept(TestCase): - except: # noqa: E722 - raise - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - udt() - self.assertIn( - "The re-raising of an exception is not yet supported.", -@@ -459,7 +460,7 @@ class TestTryExceptCaught(TestCase): - return r - return r - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - udt(True) - self.assertIn( - "Exception object cannot be stored into variable (e)", -@@ -474,7 +475,7 @@ class TestTryExceptCaught(TestCase): - except Exception: - raise - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - udt() - self.assertIn( - "The re-raising of an exception is not yet supported.", -@@ -492,7 +493,7 @@ class TestTryExceptCaught(TestCase): - except Exception: - raise - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - udt() - self.assertIn( - "The re-raising of an exception is not yet supported.", -@@ -692,6 +693,7 @@ class TestTryExceptOtherControlFlow(Test - - @expected_failure_py311 - @expected_failure_py312 -+ @expected_failure_py313 - def test_objmode(self): - @njit - def udt(): -@@ -712,6 +714,7 @@ class TestTryExceptOtherControlFlow(Test - - @expected_failure_py311 - @expected_failure_py312 -+ @expected_failure_py313 - def test_objmode_output_type(self): - def bar(x): - return np.asarray(list(reversed(x.tolist()))) -Index: numba-0.60.0/numba/tests/test_withlifting.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_withlifting.py -+++ numba-0.60.0/numba/tests/test_withlifting.py -@@ -16,7 +16,8 @@ from numba.tests.support import (MemoryL - skip_unless_scipy, linux_only, - strace_supported, strace, - expected_failure_py311, -- expected_failure_py312) -+ expected_failure_py312, -+ expected_failure_py313) - from numba.core.utils import PYVERSION - from numba.experimental import jitclass - import unittest -@@ -280,6 +281,7 @@ class TestLiftCall(BaseTestWithLifting): - - @expected_failure_py311 - @expected_failure_py312 -+ @expected_failure_py313 - def test_liftcall5(self): - self.check_extracted_with(liftcall5, expect_count=1, - expected_stdout="0\n1\n2\n3\n4\n5\nA\n") -@@ -719,6 +721,7 @@ class TestLiftObj(MemoryLeak, TestCase): - - @expected_failure_py311 - @expected_failure_py312 -+ @expected_failure_py313 - def test_case19_recursion(self): - def foo(x): - with objmode_context(): -@@ -1169,7 +1172,7 @@ class TestBogusContext(BaseTestWithLifti - with open('') as f: - pass - -- with self.assertRaises(errors.UnsupportedError) as raises: -+ with self.assertRaises(errors.UnsupportedBytecodeError) as raises: - foo() - - excstr = str(raises.exception) -Index: numba-0.60.0/numba/tests/test_sys_monitoring.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_sys_monitoring.py -+++ numba-0.60.0/numba/tests/test_sys_monitoring.py -@@ -4,7 +4,7 @@ import sys - import threading - import unittest - from unittest.mock import Mock, call --from numba.tests.support import TestCase, skip_unless_py312 -+from numba.tests.support import TestCase - from numba import jit, objmode - from numba.core.utils import PYVERSION - from numba.core.serialize import _numba_unpickle -@@ -21,7 +21,7 @@ def generate_usecase(): - return foo, call_foo - - --if PYVERSION == (3, 12): -+if PYVERSION in ((3, 12), (3, 13)): - PY_START = sys.monitoring.events.PY_START - PY_RETURN = sys.monitoring.events.PY_RETURN - RAISE = sys.monitoring.events.RAISE -@@ -36,7 +36,7 @@ TOOL2MONITORTYPE = {0 : "Debugger", - 5 : "Optimizer"} - - --@skip_unless_py312 -+@unittest.skipUnless(PYVERSION >= (3, 12), "needs Python 3.12+") - class TestMonitoring(TestCase): - # Tests the interaction of the Numba dispatcher with `sys.monitoring`. - # -@@ -724,7 +724,7 @@ class TestMonitoring(TestCase): - self.assertFalse(q2.qsize()) - - --@skip_unless_py312 -+@unittest.skipUnless(PYVERSION >= (3, 12), "needs Python 3.12+") - class TestMonitoringSelfTest(TestCase): - - def test_skipping_of_tests_if_monitoring_in_use(self): -Index: numba-0.60.0/numba/_random.c -=================================================================== ---- numba-0.60.0.orig/numba/_random.c -+++ numba-0.60.0/numba/_random.c -@@ -195,7 +195,7 @@ rnd_implicit_init(rnd_state_t *state) - Py_buffer buf; - PyGILState_STATE gilstate = PyGILState_Ensure(); - -- module = PyImport_ImportModuleNoBlock("os"); -+ module = PyImport_ImportModule("os"); - if (module == NULL) - goto error; - /* Read as many bytes as necessary to get the full entropy -Index: numba-0.60.0/numba/core/pythonapi.py -=================================================================== ---- numba-0.60.0.orig/numba/core/pythonapi.py -+++ numba-0.60.0/numba/core/pythonapi.py -@@ -919,9 +919,9 @@ class PythonAPI(object): - # Other APIs (organize them better!) - # - -- def import_module_noblock(self, modname): -+ def import_module(self, modname): - fnty = ir.FunctionType(self.pyobj, [self.cstring]) -- fn = self._get_function(fnty, name="PyImport_ImportModuleNoBlock") -+ fn = self._get_function(fnty, name="PyImport_ImportModule") - return self.builder.call(fn, [modname]) - - def call_function_objargs(self, callee, objargs): -Index: numba-0.60.0/numba/experimental/function_type.py -=================================================================== ---- numba-0.60.0.orig/numba/experimental/function_type.py -+++ numba-0.60.0/numba/experimental/function_type.py -@@ -181,7 +181,7 @@ def lower_get_wrapper_address(context, b - # caller. - - modname = context.insert_const_string(builder.module, __name__) -- numba_mod = pyapi.import_module_noblock(modname) -+ numba_mod = pyapi.import_module(modname) - numba_func = pyapi.object_getattr_string( - numba_mod, '_get_wrapper_address') - pyapi.decref(numba_mod) -@@ -263,3 +263,4 @@ def lower_cast_dispatcher_to_function_ty - llty = context.get_value_type(types.voidptr) - sfunc.pyaddr = builder.ptrtoint(val, llty) - return sfunc._getvalue() -+ -Index: numba-0.60.0/numba/typed/typeddict.py -=================================================================== ---- numba-0.60.0.orig/numba/typed/typeddict.py -+++ numba-0.60.0/numba/typed/typeddict.py -@@ -266,7 +266,7 @@ def box_dicttype(typ, val, c): - modname = c.context.insert_const_string( - c.builder.module, 'numba.typed.typeddict', - ) -- typeddict_mod = c.pyapi.import_module_noblock(modname) -+ typeddict_mod = c.pyapi.import_module(modname) - fmp_fn = c.pyapi.object_getattr_string(typeddict_mod, '_from_meminfo_ptr') - - dicttype_obj = c.pyapi.unserialize(c.pyapi.serialize_object(typ)) -Index: numba-0.60.0/numba/typed/typedlist.py -=================================================================== ---- numba-0.60.0.orig/numba/typed/typedlist.py -+++ numba-0.60.0/numba/typed/typedlist.py -@@ -471,7 +471,7 @@ def box_lsttype(typ, val, c): - modname = c.context.insert_const_string( - c.builder.module, 'numba.typed.typedlist', - ) -- typedlist_mod = c.pyapi.import_module_noblock(modname) -+ typedlist_mod = c.pyapi.import_module(modname) - fmp_fn = c.pyapi.object_getattr_string(typedlist_mod, '_from_meminfo_ptr') - - lsttype_obj = c.pyapi.unserialize(c.pyapi.serialize_object(typ)) -Index: numba-0.60.0/numba/tests/test_interpreter.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_interpreter.py -+++ numba-0.60.0/numba/tests/test_interpreter.py -@@ -5,7 +5,7 @@ import unittest - from numba import jit, njit, objmode, typeof, literally - from numba.extending import overload - from numba.core import types --from numba.core.errors import UnsupportedError -+from numba.core.errors import UnsupportedBytecodeError - from numba.tests.support import ( - TestCase, - MemoryLeakMixin, -@@ -388,7 +388,7 @@ class TestCallFunctionExPeepHole(MemoryL - arg41=1, - ) - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - njit()(inline_func)(False) - self.assertIn( - 'You can resolve this issue by moving the control flow out', -@@ -498,7 +498,7 @@ class TestCallFunctionExPeepHole(MemoryL - 1, - ) - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - njit()(inline_func)(False) - self.assertIn( - 'You can resolve this issue by moving the control flow out', -@@ -585,7 +585,7 @@ class TestCallFunctionExPeepHole(MemoryL - arg15=1 if flag else 2, - ) - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - njit()(inline_func)(False) - self.assertIn( - 'You can resolve this issue by moving the control flow out', -@@ -973,7 +973,7 @@ class TestLargeConstDict(TestCase, Memor - } - return d["S"] - -- with self.assertRaises(UnsupportedError) as raises: -+ with self.assertRaises(UnsupportedBytecodeError) as raises: - njit()(inline_func)("a_string", False) - self.assertIn( - 'You can resolve this issue by moving the control flow out', -Index: numba-0.60.0/numba/tests/test_tuples.py -=================================================================== ---- numba-0.60.0.orig/numba/tests/test_tuples.py -+++ numba-0.60.0/numba/tests/test_tuples.py -@@ -731,7 +731,7 @@ class TestTupleBuild(TestCase): - b = (3,2, 4) - return (*(b if a[0] else (5, 6)),) - -- with self.assertRaises(errors.UnsupportedError) as raises: -+ with self.assertRaises(errors.UnsupportedBytecodeError) as raises: - foo() - msg = "op_LIST_EXTEND at the start of a block" - self.assertIn(msg, str(raises.exception)) -Index: numba-0.60.0/setup.py -=================================================================== ---- numba-0.60.0.orig/setup.py -+++ numba-0.60.0/setup.py -@@ -20,7 +20,7 @@ except ImportError: - - - min_python_version = "3.9" --max_python_version = "3.13" # exclusive -+max_python_version = "3.14" # exclusive - min_numpy_build_version = "2.0.0rc1" - min_numpy_run_version = "1.22" - max_numpy_run_version = "2.1" -Index: numba-0.60.0/numba/core/boxing.py -=================================================================== ---- numba-0.60.0.orig/numba/core/boxing.py -+++ numba-0.60.0/numba/core/boxing.py -@@ -655,7 +655,7 @@ class _NumbaTypeHelper(object): - def __enter__(self): - c = self.c - numba_name = c.context.insert_const_string(c.builder.module, 'numba') -- numba_mod = c.pyapi.import_module_noblock(numba_name) -+ numba_mod = c.pyapi.import_module(numba_name) - typeof_fn = c.pyapi.object_getattr_string(numba_mod, 'typeof') - self.typeof_fn = typeof_fn - c.pyapi.decref(numba_mod) -@@ -1213,7 +1213,7 @@ def unbox_numpy_random_bitgenerator(typ, - # store the results. - # First find ctypes.cast, and ctypes.c_void_p - ctypes_name = c.context.insert_const_string(c.builder.module, 'ctypes') -- ctypes_module = c.pyapi.import_module_noblock(ctypes_name) -+ ctypes_module = c.pyapi.import_module(ctypes_name) - extra_refs.append(ctypes_module) - with cgutils.early_exit_if_null(c.builder, stack, ctypes_module): - handle_failure() -Index: numba-0.60.0/numba/pythoncapi_compat.h -=================================================================== ---- /dev/null -+++ numba-0.60.0/numba/pythoncapi_compat.h -@@ -0,0 +1,1696 @@ -+// Header file providing new C API functions to old Python versions. -+// -+// File distributed under the Zero Clause BSD (0BSD) license. -+// Copyright Contributors to the pythoncapi_compat project. -+// -+// Homepage: -+// https://github.com/python/pythoncapi_compat -+// -+// Latest version: -+// https://raw.githubusercontent.com/python/pythoncapi-compat/0041177c4f348c8952b4c8980b2c90856e61c7c7/pythoncapi_compat.h -+// -+// SPDX-License-Identifier: 0BSD -+ -+#ifndef PYTHONCAPI_COMPAT -+#define PYTHONCAPI_COMPAT -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+#include -+ -+// Python 3.11.0b4 added PyFrame_Back() to Python.h -+#if PY_VERSION_HEX < 0x030b00B4 && !defined(PYPY_VERSION) -+# include "frameobject.h" // PyFrameObject, PyFrame_GetBack() -+#endif -+ -+ -+#ifndef _Py_CAST -+# define _Py_CAST(type, expr) ((type)(expr)) -+#endif -+ -+// Static inline functions should use _Py_NULL rather than using directly NULL -+// to prevent C++ compiler warnings. On C23 and newer and on C++11 and newer, -+// _Py_NULL is defined as nullptr. -+#if (defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L) \ -+ || (defined(__cplusplus) && __cplusplus >= 201103) -+# define _Py_NULL nullptr -+#else -+# define _Py_NULL NULL -+#endif -+ -+// Cast argument to PyObject* type. -+#ifndef _PyObject_CAST -+# define _PyObject_CAST(op) _Py_CAST(PyObject*, op) -+#endif -+ -+#ifndef Py_BUILD_ASSERT -+# define Py_BUILD_ASSERT(cond) \ -+ do { \ -+ (void)sizeof(char [1 - 2 * !(cond)]); \ -+ } while(0) -+#endif -+ -+ -+// bpo-42262 added Py_NewRef() to Python 3.10.0a3 -+#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) -+static inline PyObject* _Py_NewRef(PyObject *obj) -+{ -+ Py_INCREF(obj); -+ return obj; -+} -+#define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) -+#endif -+ -+ -+// bpo-42262 added Py_XNewRef() to Python 3.10.0a3 -+#if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) -+static inline PyObject* _Py_XNewRef(PyObject *obj) -+{ -+ Py_XINCREF(obj); -+ return obj; -+} -+#define Py_XNewRef(obj) _Py_XNewRef(_PyObject_CAST(obj)) -+#endif -+ -+ -+// bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 -+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) -+static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) -+{ -+ ob->ob_refcnt = refcnt; -+} -+#define Py_SET_REFCNT(ob, refcnt) _Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) -+#endif -+ -+ -+// Py_SETREF() and Py_XSETREF() were added to Python 3.5.2. -+// It is excluded from the limited C API. -+#if (PY_VERSION_HEX < 0x03050200 && !defined(Py_SETREF)) && !defined(Py_LIMITED_API) -+#define Py_SETREF(dst, src) \ -+ do { \ -+ PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ -+ PyObject *_tmp_dst = (*_tmp_dst_ptr); \ -+ *_tmp_dst_ptr = _PyObject_CAST(src); \ -+ Py_DECREF(_tmp_dst); \ -+ } while (0) -+ -+#define Py_XSETREF(dst, src) \ -+ do { \ -+ PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ -+ PyObject *_tmp_dst = (*_tmp_dst_ptr); \ -+ *_tmp_dst_ptr = _PyObject_CAST(src); \ -+ Py_XDECREF(_tmp_dst); \ -+ } while (0) -+#endif -+ -+ -+// bpo-43753 added Py_Is(), Py_IsNone(), Py_IsTrue() and Py_IsFalse() -+// to Python 3.10.0b1. -+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_Is) -+# define Py_Is(x, y) ((x) == (y)) -+#endif -+#if PY_VERSION_HEX < 0x030A00B1 && !defined(Py_IsNone) -+# define Py_IsNone(x) Py_Is(x, Py_None) -+#endif -+#if (PY_VERSION_HEX < 0x030A00B1 || defined(PYPY_VERSION)) && !defined(Py_IsTrue) -+# define Py_IsTrue(x) Py_Is(x, Py_True) -+#endif -+#if (PY_VERSION_HEX < 0x030A00B1 || defined(PYPY_VERSION)) && !defined(Py_IsFalse) -+# define Py_IsFalse(x) Py_Is(x, Py_False) -+#endif -+ -+ -+// bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 -+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) -+static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) -+{ -+ ob->ob_type = type; -+} -+#define Py_SET_TYPE(ob, type) _Py_SET_TYPE(_PyObject_CAST(ob), type) -+#endif -+ -+ -+// bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 -+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) -+static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) -+{ -+ ob->ob_size = size; -+} -+#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size) -+#endif -+ -+ -+// bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 -+#if PY_VERSION_HEX < 0x030900B1 || defined(PYPY_VERSION) -+static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame) -+{ -+ assert(frame != _Py_NULL); -+ assert(frame->f_code != _Py_NULL); -+ return _Py_CAST(PyCodeObject*, Py_NewRef(frame->f_code)); -+} -+#endif -+ -+static inline PyCodeObject* _PyFrame_GetCodeBorrow(PyFrameObject *frame) -+{ -+ PyCodeObject *code = PyFrame_GetCode(frame); -+ Py_DECREF(code); -+ return code; -+} -+ -+ -+// bpo-40421 added PyFrame_GetBack() to Python 3.9.0b1 -+#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -+static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame) -+{ -+ assert(frame != _Py_NULL); -+ return _Py_CAST(PyFrameObject*, Py_XNewRef(frame->f_back)); -+} -+#endif -+ -+#if !defined(PYPY_VERSION) -+static inline PyFrameObject* _PyFrame_GetBackBorrow(PyFrameObject *frame) -+{ -+ PyFrameObject *back = PyFrame_GetBack(frame); -+ Py_XDECREF(back); -+ return back; -+} -+#endif -+ -+ -+// bpo-40421 added PyFrame_GetLocals() to Python 3.11.0a7 -+#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) -+static inline PyObject* PyFrame_GetLocals(PyFrameObject *frame) -+{ -+#if PY_VERSION_HEX >= 0x030400B1 -+ if (PyFrame_FastToLocalsWithError(frame) < 0) { -+ return NULL; -+ } -+#else -+ PyFrame_FastToLocals(frame); -+#endif -+ return Py_NewRef(frame->f_locals); -+} -+#endif -+ -+ -+// bpo-40421 added PyFrame_GetGlobals() to Python 3.11.0a7 -+#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) -+static inline PyObject* PyFrame_GetGlobals(PyFrameObject *frame) -+{ -+ return Py_NewRef(frame->f_globals); -+} -+#endif -+ -+ -+// bpo-40421 added PyFrame_GetBuiltins() to Python 3.11.0a7 -+#if PY_VERSION_HEX < 0x030B00A7 && !defined(PYPY_VERSION) -+static inline PyObject* PyFrame_GetBuiltins(PyFrameObject *frame) -+{ -+ return Py_NewRef(frame->f_builtins); -+} -+#endif -+ -+ -+// bpo-40421 added PyFrame_GetLasti() to Python 3.11.0b1 -+#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION) -+static inline int PyFrame_GetLasti(PyFrameObject *frame) -+{ -+#if PY_VERSION_HEX >= 0x030A00A7 -+ // bpo-27129: Since Python 3.10.0a7, f_lasti is an instruction offset, -+ // not a bytes offset anymore. Python uses 16-bit "wordcode" (2 bytes) -+ // instructions. -+ if (frame->f_lasti < 0) { -+ return -1; -+ } -+ return frame->f_lasti * 2; -+#else -+ return frame->f_lasti; -+#endif -+} -+#endif -+ -+ -+// gh-91248 added PyFrame_GetVar() to Python 3.12.0a2 -+#if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION) -+static inline PyObject* PyFrame_GetVar(PyFrameObject *frame, PyObject *name) -+{ -+ PyObject *locals, *value; -+ -+ locals = PyFrame_GetLocals(frame); -+ if (locals == NULL) { -+ return NULL; -+ } -+#if PY_VERSION_HEX >= 0x03000000 -+ value = PyDict_GetItemWithError(locals, name); -+#else -+ value = _PyDict_GetItemWithError(locals, name); -+#endif -+ Py_DECREF(locals); -+ -+ if (value == NULL) { -+ if (PyErr_Occurred()) { -+ return NULL; -+ } -+#if PY_VERSION_HEX >= 0x03000000 -+ PyErr_Format(PyExc_NameError, "variable %R does not exist", name); -+#else -+ PyErr_SetString(PyExc_NameError, "variable does not exist"); -+#endif -+ return NULL; -+ } -+ return Py_NewRef(value); -+} -+#endif -+ -+ -+// gh-91248 added PyFrame_GetVarString() to Python 3.12.0a2 -+#if PY_VERSION_HEX < 0x030C00A2 && !defined(PYPY_VERSION) -+static inline PyObject* -+PyFrame_GetVarString(PyFrameObject *frame, const char *name) -+{ -+ PyObject *name_obj, *value; -+#if PY_VERSION_HEX >= 0x03000000 -+ name_obj = PyUnicode_FromString(name); -+#else -+ name_obj = PyString_FromString(name); -+#endif -+ if (name_obj == NULL) { -+ return NULL; -+ } -+ value = PyFrame_GetVar(frame, name_obj); -+ Py_DECREF(name_obj); -+ return value; -+} -+#endif -+ -+ -+// bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 -+#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION) -+static inline PyInterpreterState * -+PyThreadState_GetInterpreter(PyThreadState *tstate) -+{ -+ assert(tstate != _Py_NULL); -+ return tstate->interp; -+} -+#endif -+ -+ -+// bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 -+#if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -+static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) -+{ -+ assert(tstate != _Py_NULL); -+ return _Py_CAST(PyFrameObject *, Py_XNewRef(tstate->frame)); -+} -+#endif -+ -+#if !defined(PYPY_VERSION) -+static inline PyFrameObject* -+_PyThreadState_GetFrameBorrow(PyThreadState *tstate) -+{ -+ PyFrameObject *frame = PyThreadState_GetFrame(tstate); -+ Py_XDECREF(frame); -+ return frame; -+} -+#endif -+ -+ -+// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 -+#if PY_VERSION_HEX < 0x030900A5 || defined(PYPY_VERSION) -+static inline PyInterpreterState* PyInterpreterState_Get(void) -+{ -+ PyThreadState *tstate; -+ PyInterpreterState *interp; -+ -+ tstate = PyThreadState_GET(); -+ if (tstate == _Py_NULL) { -+ Py_FatalError("GIL released (tstate is NULL)"); -+ } -+ interp = tstate->interp; -+ if (interp == _Py_NULL) { -+ Py_FatalError("no current interpreter"); -+ } -+ return interp; -+} -+#endif -+ -+ -+// bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 -+#if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -+static inline uint64_t PyThreadState_GetID(PyThreadState *tstate) -+{ -+ assert(tstate != _Py_NULL); -+ return tstate->id; -+} -+#endif -+ -+// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2 -+#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -+static inline void PyThreadState_EnterTracing(PyThreadState *tstate) -+{ -+ tstate->tracing++; -+#if PY_VERSION_HEX >= 0x030A00A1 -+ tstate->cframe->use_tracing = 0; -+#else -+ tstate->use_tracing = 0; -+#endif -+} -+#endif -+ -+// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2 -+#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -+static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) -+{ -+ int use_tracing = (tstate->c_tracefunc != _Py_NULL -+ || tstate->c_profilefunc != _Py_NULL); -+ tstate->tracing--; -+#if PY_VERSION_HEX >= 0x030A00A1 -+ tstate->cframe->use_tracing = use_tracing; -+#else -+ tstate->use_tracing = use_tracing; -+#endif -+} -+#endif -+ -+ -+// bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 -+// PyObject_CallNoArgs() added to PyPy 3.9.16-v7.3.11 -+#if !defined(PyObject_CallNoArgs) && PY_VERSION_HEX < 0x030900A1 -+static inline PyObject* PyObject_CallNoArgs(PyObject *func) -+{ -+ return PyObject_CallFunctionObjArgs(func, NULL); -+} -+#endif -+ -+ -+// bpo-39245 made PyObject_CallOneArg() public (previously called -+// _PyObject_CallOneArg) in Python 3.9.0a4 -+// PyObject_CallOneArg() added to PyPy 3.9.16-v7.3.11 -+#if !defined(PyObject_CallOneArg) && PY_VERSION_HEX < 0x030900A4 -+static inline PyObject* PyObject_CallOneArg(PyObject *func, PyObject *arg) -+{ -+ return PyObject_CallFunctionObjArgs(func, arg, NULL); -+} -+#endif -+ -+ -+// bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 -+#if PY_VERSION_HEX < 0x030A00A3 -+static inline int -+PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) -+{ -+ int res; -+ -+ if (!value && !PyErr_Occurred()) { -+ // PyModule_AddObject() raises TypeError in this case -+ PyErr_SetString(PyExc_SystemError, -+ "PyModule_AddObjectRef() must be called " -+ "with an exception raised if value is NULL"); -+ return -1; -+ } -+ -+ Py_XINCREF(value); -+ res = PyModule_AddObject(module, name, value); -+ if (res < 0) { -+ Py_XDECREF(value); -+ } -+ return res; -+} -+#endif -+ -+ -+// bpo-40024 added PyModule_AddType() to Python 3.9.0a5 -+#if PY_VERSION_HEX < 0x030900A5 -+static inline int PyModule_AddType(PyObject *module, PyTypeObject *type) -+{ -+ const char *name, *dot; -+ -+ if (PyType_Ready(type) < 0) { -+ return -1; -+ } -+ -+ // inline _PyType_Name() -+ name = type->tp_name; -+ assert(name != _Py_NULL); -+ dot = strrchr(name, '.'); -+ if (dot != _Py_NULL) { -+ name = dot + 1; -+ } -+ -+ return PyModule_AddObjectRef(module, name, _PyObject_CAST(type)); -+} -+#endif -+ -+ -+// bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6. -+// bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2. -+#if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -+static inline int PyObject_GC_IsTracked(PyObject* obj) -+{ -+ return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); -+} -+#endif -+ -+// bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6. -+// bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final. -+#if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION) -+static inline int PyObject_GC_IsFinalized(PyObject *obj) -+{ -+ PyGC_Head *gc = _Py_CAST(PyGC_Head*, obj) - 1; -+ return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc)); -+} -+#endif -+ -+ -+// bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 -+#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) -+static inline int _Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { -+ return Py_TYPE(ob) == type; -+} -+#define Py_IS_TYPE(ob, type) _Py_IS_TYPE(_PyObject_CAST(ob), type) -+#endif -+ -+ -+// bpo-46906 added PyFloat_Pack2() and PyFloat_Unpack2() to Python 3.11a7. -+// bpo-11734 added _PyFloat_Pack2() and _PyFloat_Unpack2() to Python 3.6.0b1. -+// Python 3.11a2 moved _PyFloat_Pack2() and _PyFloat_Unpack2() to the internal -+// C API: Python 3.11a2-3.11a6 versions are not supported. -+#if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION) -+static inline int PyFloat_Pack2(double x, char *p, int le) -+{ return _PyFloat_Pack2(x, (unsigned char*)p, le); } -+ -+static inline double PyFloat_Unpack2(const char *p, int le) -+{ return _PyFloat_Unpack2((const unsigned char *)p, le); } -+#endif -+ -+ -+// bpo-46906 added PyFloat_Pack4(), PyFloat_Pack8(), PyFloat_Unpack4() and -+// PyFloat_Unpack8() to Python 3.11a7. -+// Python 3.11a2 moved _PyFloat_Pack4(), _PyFloat_Pack8(), _PyFloat_Unpack4() -+// and _PyFloat_Unpack8() to the internal C API: Python 3.11a2-3.11a6 versions -+// are not supported. -+#if PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION) -+static inline int PyFloat_Pack4(double x, char *p, int le) -+{ return _PyFloat_Pack4(x, (unsigned char*)p, le); } -+ -+static inline int PyFloat_Pack8(double x, char *p, int le) -+{ return _PyFloat_Pack8(x, (unsigned char*)p, le); } -+ -+static inline double PyFloat_Unpack4(const char *p, int le) -+{ return _PyFloat_Unpack4((const unsigned char *)p, le); } -+ -+static inline double PyFloat_Unpack8(const char *p, int le) -+{ return _PyFloat_Unpack8((const unsigned char *)p, le); } -+#endif -+ -+ -+// gh-92154 added PyCode_GetCode() to Python 3.11.0b1 -+#if PY_VERSION_HEX < 0x030B00B1 && !defined(PYPY_VERSION) -+static inline PyObject* PyCode_GetCode(PyCodeObject *code) -+{ -+ return Py_NewRef(code->co_code); -+} -+#endif -+ -+ -+// gh-95008 added PyCode_GetVarnames() to Python 3.11.0rc1 -+#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) -+static inline PyObject* PyCode_GetVarnames(PyCodeObject *code) -+{ -+ return Py_NewRef(code->co_varnames); -+} -+#endif -+ -+// gh-95008 added PyCode_GetFreevars() to Python 3.11.0rc1 -+#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) -+static inline PyObject* PyCode_GetFreevars(PyCodeObject *code) -+{ -+ return Py_NewRef(code->co_freevars); -+} -+#endif -+ -+// gh-95008 added PyCode_GetCellvars() to Python 3.11.0rc1 -+#if PY_VERSION_HEX < 0x030B00C1 && !defined(PYPY_VERSION) -+static inline PyObject* PyCode_GetCellvars(PyCodeObject *code) -+{ -+ return Py_NewRef(code->co_cellvars); -+} -+#endif -+ -+ -+// Py_UNUSED() was added to Python 3.4.0b2. -+#if PY_VERSION_HEX < 0x030400B2 && !defined(Py_UNUSED) -+# if defined(__GNUC__) || defined(__clang__) -+# define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) -+# else -+# define Py_UNUSED(name) _unused_ ## name -+# endif -+#endif -+ -+ -+// gh-105922 added PyImport_AddModuleRef() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A0 -+static inline PyObject* PyImport_AddModuleRef(const char *name) -+{ -+ return Py_XNewRef(PyImport_AddModule(name)); -+} -+#endif -+ -+ -+// gh-105927 added PyWeakref_GetRef() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D0000 -+static inline int PyWeakref_GetRef(PyObject *ref, PyObject **pobj) -+{ -+ PyObject *obj; -+ if (ref != NULL && !PyWeakref_Check(ref)) { -+ *pobj = NULL; -+ PyErr_SetString(PyExc_TypeError, "expected a weakref"); -+ return -1; -+ } -+ obj = PyWeakref_GetObject(ref); -+ if (obj == NULL) { -+ // SystemError if ref is NULL -+ *pobj = NULL; -+ return -1; -+ } -+ if (obj == Py_None) { -+ *pobj = NULL; -+ return 0; -+ } -+ *pobj = Py_NewRef(obj); -+ return (*pobj != NULL); -+} -+#endif -+ -+ -+// bpo-36974 added PY_VECTORCALL_ARGUMENTS_OFFSET to Python 3.8b1 -+#ifndef PY_VECTORCALL_ARGUMENTS_OFFSET -+# define PY_VECTORCALL_ARGUMENTS_OFFSET (_Py_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) -+#endif -+ -+// bpo-36974 added PyVectorcall_NARGS() to Python 3.8b1 -+#if PY_VERSION_HEX < 0x030800B1 -+static inline Py_ssize_t PyVectorcall_NARGS(size_t n) -+{ -+ return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; -+} -+#endif -+ -+ -+// gh-105922 added PyObject_Vectorcall() to Python 3.9.0a4 -+#if PY_VERSION_HEX < 0x030900A4 -+static inline PyObject* -+PyObject_Vectorcall(PyObject *callable, PyObject *const *args, -+ size_t nargsf, PyObject *kwnames) -+{ -+#if PY_VERSION_HEX >= 0x030800B1 && !defined(PYPY_VERSION) -+ // bpo-36974 added _PyObject_Vectorcall() to Python 3.8.0b1 -+ return _PyObject_Vectorcall(callable, args, nargsf, kwnames); -+#else -+ PyObject *posargs = NULL, *kwargs = NULL; -+ PyObject *res; -+ Py_ssize_t nposargs, nkwargs, i; -+ -+ if (nargsf != 0 && args == NULL) { -+ PyErr_BadInternalCall(); -+ goto error; -+ } -+ if (kwnames != NULL && !PyTuple_Check(kwnames)) { -+ PyErr_BadInternalCall(); -+ goto error; -+ } -+ -+ nposargs = (Py_ssize_t)PyVectorcall_NARGS(nargsf); -+ if (kwnames) { -+ nkwargs = PyTuple_GET_SIZE(kwnames); -+ } -+ else { -+ nkwargs = 0; -+ } -+ -+ posargs = PyTuple_New(nposargs); -+ if (posargs == NULL) { -+ goto error; -+ } -+ if (nposargs) { -+ for (i=0; i < nposargs; i++) { -+ PyTuple_SET_ITEM(posargs, i, Py_NewRef(*args)); -+ args++; -+ } -+ } -+ -+ if (nkwargs) { -+ kwargs = PyDict_New(); -+ if (kwargs == NULL) { -+ goto error; -+ } -+ -+ for (i = 0; i < nkwargs; i++) { -+ PyObject *key = PyTuple_GET_ITEM(kwnames, i); -+ PyObject *value = *args; -+ args++; -+ if (PyDict_SetItem(kwargs, key, value) < 0) { -+ goto error; -+ } -+ } -+ } -+ else { -+ kwargs = NULL; -+ } -+ -+ res = PyObject_Call(callable, posargs, kwargs); -+ Py_DECREF(posargs); -+ Py_XDECREF(kwargs); -+ return res; -+ -+error: -+ Py_DECREF(posargs); -+ Py_XDECREF(kwargs); -+ return NULL; -+#endif -+} -+#endif -+ -+ -+// gh-106521 added PyObject_GetOptionalAttr() and -+// PyObject_GetOptionalAttrString() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyObject_GetOptionalAttr(PyObject *obj, PyObject *attr_name, PyObject **result) -+{ -+ // bpo-32571 added _PyObject_LookupAttr() to Python 3.7.0b1 -+#if PY_VERSION_HEX >= 0x030700B1 && !defined(PYPY_VERSION) -+ return _PyObject_LookupAttr(obj, attr_name, result); -+#else -+ *result = PyObject_GetAttr(obj, attr_name); -+ if (*result != NULL) { -+ return 1; -+ } -+ if (!PyErr_Occurred()) { -+ return 0; -+ } -+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) { -+ PyErr_Clear(); -+ return 0; -+ } -+ return -1; -+#endif -+} -+ -+static inline int -+PyObject_GetOptionalAttrString(PyObject *obj, const char *attr_name, PyObject **result) -+{ -+ PyObject *name_obj; -+ int rc; -+#if PY_VERSION_HEX >= 0x03000000 -+ name_obj = PyUnicode_FromString(attr_name); -+#else -+ name_obj = PyString_FromString(attr_name); -+#endif -+ if (name_obj == NULL) { -+ *result = NULL; -+ return -1; -+ } -+ rc = PyObject_GetOptionalAttr(obj, name_obj, result); -+ Py_DECREF(name_obj); -+ return rc; -+} -+#endif -+ -+ -+// gh-106307 added PyObject_GetOptionalAttr() and -+// PyMapping_GetOptionalItemString() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyMapping_GetOptionalItem(PyObject *obj, PyObject *key, PyObject **result) -+{ -+ *result = PyObject_GetItem(obj, key); -+ if (*result) { -+ return 1; -+ } -+ if (!PyErr_ExceptionMatches(PyExc_KeyError)) { -+ return -1; -+ } -+ PyErr_Clear(); -+ return 0; -+} -+ -+static inline int -+PyMapping_GetOptionalItemString(PyObject *obj, const char *key, PyObject **result) -+{ -+ PyObject *key_obj; -+ int rc; -+#if PY_VERSION_HEX >= 0x03000000 -+ key_obj = PyUnicode_FromString(key); -+#else -+ key_obj = PyString_FromString(key); -+#endif -+ if (key_obj == NULL) { -+ *result = NULL; -+ return -1; -+ } -+ rc = PyMapping_GetOptionalItem(obj, key_obj, result); -+ Py_DECREF(key_obj); -+ return rc; -+} -+#endif -+ -+// gh-108511 added PyMapping_HasKeyWithError() and -+// PyMapping_HasKeyStringWithError() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyMapping_HasKeyWithError(PyObject *obj, PyObject *key) -+{ -+ PyObject *res; -+ int rc = PyMapping_GetOptionalItem(obj, key, &res); -+ Py_XDECREF(res); -+ return rc; -+} -+ -+static inline int -+PyMapping_HasKeyStringWithError(PyObject *obj, const char *key) -+{ -+ PyObject *res; -+ int rc = PyMapping_GetOptionalItemString(obj, key, &res); -+ Py_XDECREF(res); -+ return rc; -+} -+#endif -+ -+ -+// gh-108511 added PyObject_HasAttrWithError() and -+// PyObject_HasAttrStringWithError() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyObject_HasAttrWithError(PyObject *obj, PyObject *attr) -+{ -+ PyObject *res; -+ int rc = PyObject_GetOptionalAttr(obj, attr, &res); -+ Py_XDECREF(res); -+ return rc; -+} -+ -+static inline int -+PyObject_HasAttrStringWithError(PyObject *obj, const char *attr) -+{ -+ PyObject *res; -+ int rc = PyObject_GetOptionalAttrString(obj, attr, &res); -+ Py_XDECREF(res); -+ return rc; -+} -+#endif -+ -+ -+// gh-106004 added PyDict_GetItemRef() and PyDict_GetItemStringRef() -+// to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyDict_GetItemRef(PyObject *mp, PyObject *key, PyObject **result) -+{ -+#if PY_VERSION_HEX >= 0x03000000 -+ PyObject *item = PyDict_GetItemWithError(mp, key); -+#else -+ PyObject *item = _PyDict_GetItemWithError(mp, key); -+#endif -+ if (item != NULL) { -+ *result = Py_NewRef(item); -+ return 1; // found -+ } -+ if (!PyErr_Occurred()) { -+ *result = NULL; -+ return 0; // not found -+ } -+ *result = NULL; -+ return -1; -+} -+ -+static inline int -+PyDict_GetItemStringRef(PyObject *mp, const char *key, PyObject **result) -+{ -+ int res; -+#if PY_VERSION_HEX >= 0x03000000 -+ PyObject *key_obj = PyUnicode_FromString(key); -+#else -+ PyObject *key_obj = PyString_FromString(key); -+#endif -+ if (key_obj == NULL) { -+ *result = NULL; -+ return -1; -+ } -+ res = PyDict_GetItemRef(mp, key_obj, result); -+ Py_DECREF(key_obj); -+ return res; -+} -+#endif -+ -+ -+// gh-106307 added PyModule_Add() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyModule_Add(PyObject *mod, const char *name, PyObject *value) -+{ -+ int res = PyModule_AddObjectRef(mod, name, value); -+ Py_XDECREF(value); -+ return res; -+} -+#endif -+ -+ -+// gh-108014 added Py_IsFinalizing() to Python 3.13.0a1 -+// bpo-1856 added _Py_Finalizing to Python 3.2.1b1. -+// _Py_IsFinalizing() was added to PyPy 7.3.0. -+#if (0x030201B1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030D00A1) \ -+ && (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x7030000) -+static inline int Py_IsFinalizing(void) -+{ -+#if PY_VERSION_HEX >= 0x030700A1 -+ // _Py_IsFinalizing() was added to Python 3.7.0a1. -+ return _Py_IsFinalizing(); -+#else -+ return (_Py_Finalizing != NULL); -+#endif -+} -+#endif -+ -+ -+// gh-108323 added PyDict_ContainsString() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int PyDict_ContainsString(PyObject *op, const char *key) -+{ -+ PyObject *key_obj = PyUnicode_FromString(key); -+ if (key_obj == NULL) { -+ return -1; -+ } -+ int res = PyDict_Contains(op, key_obj); -+ Py_DECREF(key_obj); -+ return res; -+} -+#endif -+ -+ -+// gh-108445 added PyLong_AsInt() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int PyLong_AsInt(PyObject *obj) -+{ -+#ifdef PYPY_VERSION -+ long value = PyLong_AsLong(obj); -+ if (value == -1 && PyErr_Occurred()) { -+ return -1; -+ } -+ if (value < (long)INT_MIN || (long)INT_MAX < value) { -+ PyErr_SetString(PyExc_OverflowError, -+ "Python int too large to convert to C int"); -+ return -1; -+ } -+ return (int)value; -+#else -+ return _PyLong_AsInt(obj); -+#endif -+} -+#endif -+ -+ -+// gh-107073 added PyObject_VisitManagedDict() to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) -+{ -+ PyObject **dict = _PyObject_GetDictPtr(obj); -+ if (*dict == NULL) { -+ return -1; -+ } -+ Py_VISIT(*dict); -+ return 0; -+} -+ -+static inline void -+PyObject_ClearManagedDict(PyObject *obj) -+{ -+ PyObject **dict = _PyObject_GetDictPtr(obj); -+ if (*dict == NULL) { -+ return; -+ } -+ Py_CLEAR(*dict); -+} -+#endif -+ -+// gh-108867 added PyThreadState_GetUnchecked() to Python 3.13.0a1 -+// Python 3.5.2 added _PyThreadState_UncheckedGet(). -+#if PY_VERSION_HEX >= 0x03050200 && PY_VERSION_HEX < 0x030D00A1 -+static inline PyThreadState* -+PyThreadState_GetUnchecked(void) -+{ -+ return _PyThreadState_UncheckedGet(); -+} -+#endif -+ -+// gh-110289 added PyUnicode_EqualToUTF8() and PyUnicode_EqualToUTF8AndSize() -+// to Python 3.13.0a1 -+#if PY_VERSION_HEX < 0x030D00A1 -+static inline int -+PyUnicode_EqualToUTF8AndSize(PyObject *unicode, const char *str, Py_ssize_t str_len) -+{ -+ Py_ssize_t len; -+ const void *utf8; -+ PyObject *exc_type, *exc_value, *exc_tb; -+ int res; -+ -+ // API cannot report errors so save/restore the exception -+ PyErr_Fetch(&exc_type, &exc_value, &exc_tb); -+ -+ // Python 3.3.0a1 added PyUnicode_AsUTF8AndSize() -+#if PY_VERSION_HEX >= 0x030300A1 -+ if (PyUnicode_IS_ASCII(unicode)) { -+ utf8 = PyUnicode_DATA(unicode); -+ len = PyUnicode_GET_LENGTH(unicode); -+ } -+ else { -+ utf8 = PyUnicode_AsUTF8AndSize(unicode, &len); -+ if (utf8 == NULL) { -+ // Memory allocation failure. The API cannot report error, -+ // so ignore the exception and return 0. -+ res = 0; -+ goto done; -+ } -+ } -+ -+ if (len != str_len) { -+ res = 0; -+ goto done; -+ } -+ res = (memcmp(utf8, str, (size_t)len) == 0); -+#else -+ PyObject *bytes = PyUnicode_AsUTF8String(unicode); -+ if (bytes == NULL) { -+ // Memory allocation failure. The API cannot report error, -+ // so ignore the exception and return 0. -+ res = 0; -+ goto done; -+ } -+ -+#if PY_VERSION_HEX >= 0x03000000 -+ len = PyBytes_GET_SIZE(bytes); -+ utf8 = PyBytes_AS_STRING(bytes); -+#else -+ len = PyString_GET_SIZE(bytes); -+ utf8 = PyString_AS_STRING(bytes); -+#endif -+ if (len != str_len) { -+ Py_DECREF(bytes); -+ res = 0; -+ goto done; -+ } -+ -+ res = (memcmp(utf8, str, (size_t)len) == 0); -+ Py_DECREF(bytes); -+#endif -+ -+done: -+ PyErr_Restore(exc_type, exc_value, exc_tb); -+ return res; -+} -+ -+static inline int -+PyUnicode_EqualToUTF8(PyObject *unicode, const char *str) -+{ -+ return PyUnicode_EqualToUTF8AndSize(unicode, str, (Py_ssize_t)strlen(str)); -+} -+#endif -+ -+ -+// gh-111138 added PyList_Extend() and PyList_Clear() to Python 3.13.0a2 -+#if PY_VERSION_HEX < 0x030D00A2 -+static inline int -+PyList_Extend(PyObject *list, PyObject *iterable) -+{ -+ return PyList_SetSlice(list, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, iterable); -+} -+ -+static inline int -+PyList_Clear(PyObject *list) -+{ -+ return PyList_SetSlice(list, 0, PY_SSIZE_T_MAX, NULL); -+} -+#endif -+ -+// gh-111262 added PyDict_Pop() and PyDict_PopString() to Python 3.13.0a2 -+#if PY_VERSION_HEX < 0x030D00A2 -+static inline int -+PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result) -+{ -+ PyObject *value; -+ -+ if (!PyDict_Check(dict)) { -+ PyErr_BadInternalCall(); -+ if (result) { -+ *result = NULL; -+ } -+ return -1; -+ } -+ -+ // bpo-16991 added _PyDict_Pop() to Python 3.5.0b2. -+ // Python 3.6.0b3 changed _PyDict_Pop() first argument type to PyObject*. -+ // Python 3.13.0a1 removed _PyDict_Pop(). -+#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x030500b2 || PY_VERSION_HEX >= 0x030D0000 -+ value = PyObject_CallMethod(dict, "pop", "O", key); -+#elif PY_VERSION_HEX < 0x030600b3 -+ value = _PyDict_Pop(_Py_CAST(PyDictObject*, dict), key, NULL); -+#else -+ value = _PyDict_Pop(dict, key, NULL); -+#endif -+ if (value == NULL) { -+ if (result) { -+ *result = NULL; -+ } -+ if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_KeyError)) { -+ return -1; -+ } -+ PyErr_Clear(); -+ return 0; -+ } -+ if (result) { -+ *result = value; -+ } -+ else { -+ Py_DECREF(value); -+ } -+ return 1; -+} -+ -+static inline int -+PyDict_PopString(PyObject *dict, const char *key, PyObject **result) -+{ -+ PyObject *key_obj = PyUnicode_FromString(key); -+ if (key_obj == NULL) { -+ if (result != NULL) { -+ *result = NULL; -+ } -+ return -1; -+ } -+ -+ int res = PyDict_Pop(dict, key_obj, result); -+ Py_DECREF(key_obj); -+ return res; -+} -+#endif -+ -+ -+#if PY_VERSION_HEX < 0x030200A4 -+// Python 3.2.0a4 added Py_hash_t type -+typedef Py_ssize_t Py_hash_t; -+#endif -+ -+ -+// gh-111545 added Py_HashPointer() to Python 3.13.0a3 -+#if PY_VERSION_HEX < 0x030D00A3 -+static inline Py_hash_t Py_HashPointer(const void *ptr) -+{ -+#if PY_VERSION_HEX >= 0x030900A4 && !defined(PYPY_VERSION) -+ return _Py_HashPointer(ptr); -+#else -+ return _Py_HashPointer(_Py_CAST(void*, ptr)); -+#endif -+} -+#endif -+ -+ -+// Python 3.13a4 added a PyTime API. -+// Use the private API added to Python 3.5. -+#if PY_VERSION_HEX < 0x030D00A4 && PY_VERSION_HEX >= 0x03050000 -+typedef _PyTime_t PyTime_t; -+#define PyTime_MIN _PyTime_MIN -+#define PyTime_MAX _PyTime_MAX -+ -+static inline double PyTime_AsSecondsDouble(PyTime_t t) -+{ return _PyTime_AsSecondsDouble(t); } -+ -+static inline int PyTime_Monotonic(PyTime_t *result) -+{ return _PyTime_GetMonotonicClockWithInfo(result, NULL); } -+ -+static inline int PyTime_Time(PyTime_t *result) -+{ return _PyTime_GetSystemClockWithInfo(result, NULL); } -+ -+static inline int PyTime_PerfCounter(PyTime_t *result) -+{ -+#if PY_VERSION_HEX >= 0x03070000 && !defined(PYPY_VERSION) -+ return _PyTime_GetPerfCounterWithInfo(result, NULL); -+#elif PY_VERSION_HEX >= 0x03070000 -+ // Call time.perf_counter_ns() and convert Python int object to PyTime_t. -+ // Cache time.perf_counter_ns() function for best performance. -+ static PyObject *func = NULL; -+ if (func == NULL) { -+ PyObject *mod = PyImport_ImportModule("time"); -+ if (mod == NULL) { -+ return -1; -+ } -+ -+ func = PyObject_GetAttrString(mod, "perf_counter_ns"); -+ Py_DECREF(mod); -+ if (func == NULL) { -+ return -1; -+ } -+ } -+ -+ PyObject *res = PyObject_CallNoArgs(func); -+ if (res == NULL) { -+ return -1; -+ } -+ long long value = PyLong_AsLongLong(res); -+ Py_DECREF(res); -+ -+ if (value == -1 && PyErr_Occurred()) { -+ return -1; -+ } -+ -+ Py_BUILD_ASSERT(sizeof(value) >= sizeof(PyTime_t)); -+ *result = (PyTime_t)value; -+ return 0; -+#else -+ // Call time.perf_counter() and convert C double to PyTime_t. -+ // Cache time.perf_counter() function for best performance. -+ static PyObject *func = NULL; -+ if (func == NULL) { -+ PyObject *mod = PyImport_ImportModule("time"); -+ if (mod == NULL) { -+ return -1; -+ } -+ -+ func = PyObject_GetAttrString(mod, "perf_counter"); -+ Py_DECREF(mod); -+ if (func == NULL) { -+ return -1; -+ } -+ } -+ -+ PyObject *res = PyObject_CallNoArgs(func); -+ if (res == NULL) { -+ return -1; -+ } -+ double d = PyFloat_AsDouble(res); -+ Py_DECREF(res); -+ -+ if (d == -1.0 && PyErr_Occurred()) { -+ return -1; -+ } -+ -+ // Avoid floor() to avoid having to link to libm -+ *result = (PyTime_t)(d * 1e9); -+ return 0; -+#endif -+} -+ -+#endif -+ -+// gh-111389 added hash constants to Python 3.13.0a5. These constants were -+// added first as private macros to Python 3.4.0b1 and PyPy 7.3.9. -+#if (!defined(PyHASH_BITS) \ -+ && ((!defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x030400B1) \ -+ || (defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03070000 \ -+ && PYPY_VERSION_NUM >= 0x07090000))) -+# define PyHASH_BITS _PyHASH_BITS -+# define PyHASH_MODULUS _PyHASH_MODULUS -+# define PyHASH_INF _PyHASH_INF -+# define PyHASH_IMAG _PyHASH_IMAG -+#endif -+ -+ -+// gh-111545 added Py_GetConstant() and Py_GetConstantBorrowed() -+// to Python 3.13.0a6 -+#if PY_VERSION_HEX < 0x030D00A6 && !defined(Py_CONSTANT_NONE) -+ -+#define Py_CONSTANT_NONE 0 -+#define Py_CONSTANT_FALSE 1 -+#define Py_CONSTANT_TRUE 2 -+#define Py_CONSTANT_ELLIPSIS 3 -+#define Py_CONSTANT_NOT_IMPLEMENTED 4 -+#define Py_CONSTANT_ZERO 5 -+#define Py_CONSTANT_ONE 6 -+#define Py_CONSTANT_EMPTY_STR 7 -+#define Py_CONSTANT_EMPTY_BYTES 8 -+#define Py_CONSTANT_EMPTY_TUPLE 9 -+ -+static inline PyObject* Py_GetConstant(unsigned int constant_id) -+{ -+ static PyObject* constants[Py_CONSTANT_EMPTY_TUPLE + 1] = {NULL}; -+ -+ if (constants[Py_CONSTANT_NONE] == NULL) { -+ constants[Py_CONSTANT_NONE] = Py_None; -+ constants[Py_CONSTANT_FALSE] = Py_False; -+ constants[Py_CONSTANT_TRUE] = Py_True; -+ constants[Py_CONSTANT_ELLIPSIS] = Py_Ellipsis; -+ constants[Py_CONSTANT_NOT_IMPLEMENTED] = Py_NotImplemented; -+ -+ constants[Py_CONSTANT_ZERO] = PyLong_FromLong(0); -+ if (constants[Py_CONSTANT_ZERO] == NULL) { -+ goto fatal_error; -+ } -+ -+ constants[Py_CONSTANT_ONE] = PyLong_FromLong(1); -+ if (constants[Py_CONSTANT_ONE] == NULL) { -+ goto fatal_error; -+ } -+ -+ constants[Py_CONSTANT_EMPTY_STR] = PyUnicode_FromStringAndSize("", 0); -+ if (constants[Py_CONSTANT_EMPTY_STR] == NULL) { -+ goto fatal_error; -+ } -+ -+ constants[Py_CONSTANT_EMPTY_BYTES] = PyBytes_FromStringAndSize("", 0); -+ if (constants[Py_CONSTANT_EMPTY_BYTES] == NULL) { -+ goto fatal_error; -+ } -+ -+ constants[Py_CONSTANT_EMPTY_TUPLE] = PyTuple_New(0); -+ if (constants[Py_CONSTANT_EMPTY_TUPLE] == NULL) { -+ goto fatal_error; -+ } -+ // goto dance to avoid compiler warnings about Py_FatalError() -+ goto init_done; -+ -+fatal_error: -+ // This case should never happen -+ Py_FatalError("Py_GetConstant() failed to get constants"); -+ } -+ -+init_done: -+ if (constant_id <= Py_CONSTANT_EMPTY_TUPLE) { -+ return Py_NewRef(constants[constant_id]); -+ } -+ else { -+ PyErr_BadInternalCall(); -+ return NULL; -+ } -+} -+ -+static inline PyObject* Py_GetConstantBorrowed(unsigned int constant_id) -+{ -+ PyObject *obj = Py_GetConstant(constant_id); -+ Py_XDECREF(obj); -+ return obj; -+} -+#endif -+ -+ -+// gh-114329 added PyList_GetItemRef() to Python 3.13.0a4 -+#if PY_VERSION_HEX < 0x030D00A4 -+static inline PyObject * -+PyList_GetItemRef(PyObject *op, Py_ssize_t index) -+{ -+ PyObject *item = PyList_GetItem(op, index); -+ Py_XINCREF(item); -+ return item; -+} -+#endif -+ -+ -+// gh-114329 added PyList_GetItemRef() to Python 3.13.0a4 -+#if PY_VERSION_HEX < 0x030D00A4 -+static inline int -+PyDict_SetDefaultRef(PyObject *d, PyObject *key, PyObject *default_value, -+ PyObject **result) -+{ -+ PyObject *value; -+ if (PyDict_GetItemRef(d, key, &value) < 0) { -+ // get error -+ if (result) { -+ *result = NULL; -+ } -+ return -1; -+ } -+ if (value != NULL) { -+ // present -+ if (result) { -+ *result = value; -+ } -+ else { -+ Py_DECREF(value); -+ } -+ return 1; -+ } -+ -+ // missing: set the item -+ if (PyDict_SetItem(d, key, default_value) < 0) { -+ // set error -+ if (result) { -+ *result = NULL; -+ } -+ return -1; -+ } -+ if (result) { -+ *result = Py_NewRef(default_value); -+ } -+ return 0; -+} -+#endif -+ -+#if PY_VERSION_HEX < 0x030D00B3 -+# define Py_BEGIN_CRITICAL_SECTION(op) { -+# define Py_END_CRITICAL_SECTION() } -+# define Py_BEGIN_CRITICAL_SECTION2(a, b) { -+# define Py_END_CRITICAL_SECTION2() } -+#endif -+ -+#if PY_VERSION_HEX < 0x030E0000 && PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION) -+typedef struct PyUnicodeWriter PyUnicodeWriter; -+ -+static inline void PyUnicodeWriter_Discard(PyUnicodeWriter *writer) -+{ -+ _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer); -+ PyMem_Free(writer); -+} -+ -+static inline PyUnicodeWriter* PyUnicodeWriter_Create(Py_ssize_t length) -+{ -+ if (length < 0) { -+ PyErr_SetString(PyExc_ValueError, -+ "length must be positive"); -+ return NULL; -+ } -+ -+ const size_t size = sizeof(_PyUnicodeWriter); -+ PyUnicodeWriter *pub_writer = (PyUnicodeWriter *)PyMem_Malloc(size); -+ if (pub_writer == _Py_NULL) { -+ PyErr_NoMemory(); -+ return _Py_NULL; -+ } -+ _PyUnicodeWriter *writer = (_PyUnicodeWriter *)pub_writer; -+ -+ _PyUnicodeWriter_Init(writer); -+ if (_PyUnicodeWriter_Prepare(writer, length, 127) < 0) { -+ PyUnicodeWriter_Discard(pub_writer); -+ return NULL; -+ } -+ writer->overallocate = 1; -+ return pub_writer; -+} -+ -+static inline PyObject* PyUnicodeWriter_Finish(PyUnicodeWriter *writer) -+{ -+ PyObject *str = _PyUnicodeWriter_Finish((_PyUnicodeWriter*)writer); -+ assert(((_PyUnicodeWriter*)writer)->buffer == NULL); -+ PyMem_Free(writer); -+ return str; -+} -+ -+static inline int -+PyUnicodeWriter_WriteChar(PyUnicodeWriter *writer, Py_UCS4 ch) -+{ -+ if (ch > 0x10ffff) { -+ PyErr_SetString(PyExc_ValueError, -+ "character must be in range(0x110000)"); -+ return -1; -+ } -+ -+ return _PyUnicodeWriter_WriteChar((_PyUnicodeWriter*)writer, ch); -+} -+ -+static inline int -+PyUnicodeWriter_WriteStr(PyUnicodeWriter *writer, PyObject *obj) -+{ -+ PyObject *str = PyObject_Str(obj); -+ if (str == NULL) { -+ return -1; -+ } -+ -+ int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str); -+ Py_DECREF(str); -+ return res; -+} -+ -+static inline int -+PyUnicodeWriter_WriteRepr(PyUnicodeWriter *writer, PyObject *obj) -+{ -+ PyObject *str = PyObject_Repr(obj); -+ if (str == NULL) { -+ return -1; -+ } -+ -+ int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str); -+ Py_DECREF(str); -+ return res; -+} -+ -+static inline int -+PyUnicodeWriter_WriteUTF8(PyUnicodeWriter *writer, -+ const char *str, Py_ssize_t size) -+{ -+ if (size < 0) { -+ size = (Py_ssize_t)strlen(str); -+ } -+ -+ PyObject *str_obj = PyUnicode_FromStringAndSize(str, size); -+ if (str_obj == _Py_NULL) { -+ return -1; -+ } -+ -+ int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str_obj); -+ Py_DECREF(str_obj); -+ return res; -+} -+ -+static inline int -+PyUnicodeWriter_WriteWideChar(PyUnicodeWriter *writer, -+ const wchar_t *str, Py_ssize_t size) -+{ -+ if (size < 0) { -+ size = (Py_ssize_t)wcslen(str); -+ } -+ -+ PyObject *str_obj = PyUnicode_FromWideChar(str, size); -+ if (str_obj == _Py_NULL) { -+ return -1; -+ } -+ -+ int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str_obj); -+ Py_DECREF(str_obj); -+ return res; -+} -+ -+static inline int -+PyUnicodeWriter_WriteSubstring(PyUnicodeWriter *writer, PyObject *str, -+ Py_ssize_t start, Py_ssize_t end) -+{ -+ if (!PyUnicode_Check(str)) { -+ PyErr_Format(PyExc_TypeError, "expect str, not %T", str); -+ return -1; -+ } -+ if (start < 0 || start > end) { -+ PyErr_Format(PyExc_ValueError, "invalid start argument"); -+ return -1; -+ } -+ if (end > PyUnicode_GET_LENGTH(str)) { -+ PyErr_Format(PyExc_ValueError, "invalid end argument"); -+ return -1; -+ } -+ -+ return _PyUnicodeWriter_WriteSubstring((_PyUnicodeWriter*)writer, str, -+ start, end); -+} -+ -+static inline int -+PyUnicodeWriter_Format(PyUnicodeWriter *writer, const char *format, ...) -+{ -+ va_list vargs; -+ va_start(vargs, format); -+ PyObject *str = PyUnicode_FromFormatV(format, vargs); -+ va_end(vargs); -+ if (str == _Py_NULL) { -+ return -1; -+ } -+ -+ int res = _PyUnicodeWriter_WriteStr((_PyUnicodeWriter*)writer, str); -+ Py_DECREF(str); -+ return res; -+} -+#endif // PY_VERSION_HEX < 0x030E0000 -+ -+// gh-116560 added PyLong_GetSign() to Python 3.14.0a0 -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline int PyLong_GetSign(PyObject *obj, int *sign) -+{ -+ if (!PyLong_Check(obj)) { -+ PyErr_Format(PyExc_TypeError, "expect int, got %s", Py_TYPE(obj)->tp_name); -+ return -1; -+ } -+ -+ *sign = _PyLong_Sign(obj); -+ return 0; -+} -+#endif -+ -+ -+// gh-124502 added PyUnicode_Equal() to Python 3.14.0a0 -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline int PyUnicode_Equal(PyObject *str1, PyObject *str2) -+{ -+ if (!PyUnicode_Check(str1)) { -+ PyErr_Format(PyExc_TypeError, "first argument must be str, not %s", -+ Py_TYPE(str1)->tp_name); -+ return -1; -+ } -+ if (!PyUnicode_Check(str2)) { -+ PyErr_Format(PyExc_TypeError, "second argument must be str, not %s", -+ Py_TYPE(str2)->tp_name); -+ return -1; -+ } -+ -+#if PY_VERSION_HEX >= 0x030d0000 && !defined(PYPY_VERSION) -+ PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *str1, PyObject *str2); -+ -+ return _PyUnicode_Equal(str1, str2); -+#elif PY_VERSION_HEX >= 0x03060000 && !defined(PYPY_VERSION) -+ return _PyUnicode_EQ(str1, str2); -+#elif PY_VERSION_HEX >= 0x03090000 && defined(PYPY_VERSION) -+ return _PyUnicode_EQ(str1, str2); -+#else -+ return (PyUnicode_Compare(str1, str2) == 0); -+#endif -+} -+#endif -+ -+ -+// gh-121645 added PyBytes_Join() to Python 3.14.0a0 -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable) -+{ -+ return _PyBytes_Join(sep, iterable); -+} -+#endif -+ -+ -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline Py_hash_t Py_HashBuffer(const void *ptr, Py_ssize_t len) -+{ -+#if PY_VERSION_HEX >= 0x03000000 && !defined(PYPY_VERSION) -+ PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void *src, Py_ssize_t len); -+ -+ return _Py_HashBytes(ptr, len); -+#else -+ Py_hash_t hash; -+ PyObject *bytes = PyBytes_FromStringAndSize((const char*)ptr, len); -+ if (bytes == NULL) { -+ return -1; -+ } -+ hash = PyObject_Hash(bytes); -+ Py_DECREF(bytes); -+ return hash; -+#endif -+} -+#endif -+ -+ -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline int PyIter_NextItem(PyObject *iter, PyObject **item) -+{ -+ iternextfunc tp_iternext; -+ -+ assert(iter != NULL); -+ assert(item != NULL); -+ -+ tp_iternext = Py_TYPE(iter)->tp_iternext; -+ if (tp_iternext == NULL) { -+ *item = NULL; -+ PyErr_Format(PyExc_TypeError, "expected an iterator, got '%s'", -+ Py_TYPE(iter)->tp_name); -+ return -1; -+ } -+ -+ if ((*item = tp_iternext(iter))) { -+ return 1; -+ } -+ if (!PyErr_Occurred()) { -+ return 0; -+ } -+ if (PyErr_ExceptionMatches(PyExc_StopIteration)) { -+ PyErr_Clear(); -+ return 0; -+ } -+ return -1; -+} -+#endif -+ -+ -+#if PY_VERSION_HEX < 0x030E00A0 -+static inline PyObject* PyLong_FromInt32(int32_t value) -+{ -+ Py_BUILD_ASSERT(sizeof(long) >= 4); -+ return PyLong_FromLong(value); -+} -+ -+static inline PyObject* PyLong_FromInt64(int64_t value) -+{ -+ Py_BUILD_ASSERT(sizeof(long long) >= 8); -+ return PyLong_FromLongLong(value); -+} -+ -+static inline PyObject* PyLong_FromUInt32(uint32_t value) -+{ -+ Py_BUILD_ASSERT(sizeof(unsigned long) >= 4); -+ return PyLong_FromUnsignedLong(value); -+} -+ -+static inline PyObject* PyLong_FromUInt64(uint64_t value) -+{ -+ Py_BUILD_ASSERT(sizeof(unsigned long long) >= 8); -+ return PyLong_FromUnsignedLongLong(value); -+} -+ -+static inline int PyLong_AsInt32(PyObject *obj, int32_t *pvalue) -+{ -+ Py_BUILD_ASSERT(sizeof(int) == 4); -+ int value = PyLong_AsInt(obj); -+ if (value == -1 && PyErr_Occurred()) { -+ return -1; -+ } -+ *pvalue = (int32_t)value; -+ return 0; -+} -+ -+static inline int PyLong_AsInt64(PyObject *obj, int64_t *pvalue) -+{ -+ Py_BUILD_ASSERT(sizeof(long long) == 8); -+ long long value = PyLong_AsLongLong(obj); -+ if (value == -1 && PyErr_Occurred()) { -+ return -1; -+ } -+ *pvalue = (int64_t)value; -+ return 0; -+} -+ -+static inline int PyLong_AsUInt32(PyObject *obj, uint32_t *pvalue) -+{ -+ Py_BUILD_ASSERT(sizeof(long) >= 4); -+ unsigned long value = PyLong_AsUnsignedLong(obj); -+ if (value == (unsigned long)-1 && PyErr_Occurred()) { -+ return -1; -+ } -+#if SIZEOF_LONG > 4 -+ if ((unsigned long)UINT32_MAX < value) { -+ PyErr_SetString(PyExc_OverflowError, -+ "Python int too large to convert to C uint32_t"); -+ return -1; -+ } -+#endif -+ *pvalue = (uint32_t)value; -+ return 0; -+} -+ -+static inline int PyLong_AsUInt64(PyObject *obj, uint64_t *pvalue) -+{ -+ Py_BUILD_ASSERT(sizeof(long long) == 8); -+ unsigned long long value = PyLong_AsUnsignedLongLong(obj); -+ if (value == (unsigned long long)-1 && PyErr_Occurred()) { -+ return -1; -+ } -+ *pvalue = (uint64_t)value; -+ return 0; -+} -+#endif -+ -+ -+#ifdef __cplusplus -+} -+#endif -+#endif // PYTHONCAPI_COMPAT diff --git a/python-numba.changes b/python-numba.changes index eadcd3f..243df35 100644 --- a/python-numba.changes +++ b/python-numba.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Thu Feb 6 19:21:03 UTC 2025 - Ben Greiner + +- Remove bogus skip-test_noinline_on_main_call.patch, it was fixed + upstream in 0.61 +- Handle c++ development files for devel package + +------------------------------------------------------------------- +Wed Feb 5 17:01:37 UTC 2025 - Matej Cepl + +- Update to 0.61.0: + Major Numba release adding Python 3.13 and NumPy 2.1 support. + Detailed changelog at https://numba.readthedocs.io/en/stable/release/0.61.0-notes.html + Highlights: + - Add initial implementation for a new type system + - Python 3.13 support + - Dropped support for Python 3.9 + - Update the minimum supported NumPy version to 1.24 + - Added Support for NumPy 2.1 +- Remove upstreamed patches: + - numpy21.patch + - py313.patch +- Add skip-test_noinline_on_main_call.patch to skip + test_noinline_on_main_call (gh#numba/numba#9658). + ------------------------------------------------------------------- Fri Nov 22 09:42:21 UTC 2024 - Markéta Machová diff --git a/python-numba.spec b/python-numba.spec index 8018c8e..f780e66 100644 --- a/python-numba.spec +++ b/python-numba.spec @@ -1,7 +1,7 @@ # # spec file for package python-numba # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -32,9 +32,6 @@ ExclusiveArch: x86_64 %ix86 ppc64le %arm aarch64 %else %bcond_without test %define psuffix -%{flavor} -%if "%{flavor}" != "test-py39" -%define skip_python39 1 -%endif %if "%{flavor}" != "test-py310" %define skip_python310 1 %endif @@ -57,7 +54,7 @@ ExcludeArch: s390x ppc64 %ix86 %arm %endif %endif Name: python-numba%{?psuffix} -Version: 0.60.0 +Version: 0.61.0 Release: 0 Summary: NumPy-aware optimizing compiler for Python using LLVM License: BSD-2-Clause @@ -66,11 +63,7 @@ URL: https://numba.pydata.org/ Source: https://files.pythonhosted.org/packages/source/n/numba/numba-%{version}.tar.gz # PATCH-FIX-OPENSUSE skip tests failing due to OBS specifics Patch3: skip-failing-tests.patch -# PATCH-FIX-UPSTREAM https://github.com/numba/numba/pull/9741 Add Support for NumPy 2.1 -Patch4: numpy21.patch -# PATCH-FIX-UPSTREAM https://github.com/numba/numba/pull/9682 Python 3.13 support -Patch5: py313.patch -BuildRequires: %{python_module devel >= 3.9} +BuildRequires: %{python_module devel >= 3.10} BuildRequires: %{python_module numpy-devel >= %{min_numpy_ver} with %python-numpy-devel < %{max_numpy_ver}} BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools} @@ -79,7 +72,7 @@ BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: python-rpm-macros BuildRequires: (tbb-devel >= 2021) -Requires: (python-llvmlite >= 0.43 with python-llvmlite < 0.44) +Requires: (python-llvmlite >= 0.44 with python-llvmlite < 0.45) Requires: (python-numpy >= %{min_numpy_ver} with python-numpy < %{max_numpy_ver}) Requires(post): update-alternatives Requires(postun): update-alternatives @@ -151,7 +144,7 @@ export CFLAGS="%{optflags} -fPIC" %pyproject_install %{python_expand # %fdupes %{buildroot}%{$python_sitearch} -find %{buildroot}%{$python_sitearch} -name '*.[ch]' > devel-files0-%{$python_bin_suffix}.files +find %{buildroot}%{$python_sitearch} -name '*.[ch]' -o -name '*.[ch]pp' > devel-files0-%{$python_bin_suffix}.files sed 's|^%{buildroot}||' devel-files0-%{$python_bin_suffix}.files > devel-files-%{$python_bin_suffix}.files sed 's|^%{buildroot}|%%exclude |' devel-files0-%{$python_bin_suffix}.files > devel-files-exclude-%{$python_bin_suffix}.files } diff --git a/skip-failing-tests.patch b/skip-failing-tests.patch index a8e5cac..d386a35 100644 --- a/skip-failing-tests.patch +++ b/skip-failing-tests.patch @@ -1,54 +1,12 @@ --- + numba/tests/test_cli.py | 1 + + numba/tests/test_mathlib.py | 1 + numba/tests/test_parfors.py | 5 +++-- numba/tests/test_parfors_passes.py | 1 + - 2 files changed, 4 insertions(+), 2 deletions(-) + 4 files changed, 6 insertions(+), 2 deletions(-) -Index: numba-0.59.1/numba/tests/test_parfors.py -=================================================================== ---- numba-0.59.1.orig/numba/tests/test_parfors.py -+++ numba-0.59.1/numba/tests/test_parfors.py -@@ -1199,6 +1199,7 @@ class TestParforNumPy(TestParforsBase): - self.check_variants(test_impl2, data_gen) - self.count_parfors_variants(test_impl2, data_gen) - -+ @unittest.skip("Fails on type check in OBS") - def test_ndarray_fill(self): - def test_impl(x): - x.fill(7.0) -@@ -4659,7 +4660,7 @@ class TestParforsVectorizer(TestPrangeBa - - return asm - -- @linux_only -+ @unittest.skip("Our x86_64 asm is most probably different from the upstream one.") - @TestCase.run_test_in_subprocess - def test_vectorizer_fastmath_asm(self): - """ This checks that if fastmath is set and the underlying hardware -@@ -4700,7 +4701,7 @@ class TestParforsVectorizer(TestPrangeBa - # check no zmm addressing is present - self.assertTrue('zmm' not in v) - -- @linux_only -+ @unittest.skip("Our x86_64 asm is most probably different from the upstream one.") - @TestCase.run_test_in_subprocess(envvars={'NUMBA_BOUNDSCHECK': '0'}) - def test_unsigned_refusal_to_vectorize(self): - """ This checks that if fastmath is set and the underlying hardware -Index: numba-0.59.1/numba/tests/test_parfors_passes.py -=================================================================== ---- numba-0.59.1.orig/numba/tests/test_parfors_passes.py -+++ numba-0.59.1/numba/tests/test_parfors_passes.py -@@ -514,6 +514,7 @@ class TestConvertLoopPass(BaseTest): - str(raises.exception), - ) - -+ @unittest.skip("Fails on type check in OBS") - def test_init_prange(self): - def test_impl(): - n = 20 -Index: numba-0.59.1/numba/tests/test_cli.py -=================================================================== ---- numba-0.59.1.orig/numba/tests/test_cli.py -+++ numba-0.59.1/numba/tests/test_cli.py +--- a/numba/tests/test_cli.py ++++ b/numba/tests/test_cli.py @@ -264,6 +264,7 @@ class TestGDBCLIInfoBrokenGdbs(TestCase) self.assertIn("No such file or directory", stdout) self.assertIn(path, stdout) @@ -57,11 +15,9 @@ Index: numba-0.59.1/numba/tests/test_cli.py def test_nonsense_gdb_binary(self): # Tests that a nonsense binary specified as gdb it picked up ok env = os.environ.copy() -Index: numba-0.59.1/numba/tests/test_mathlib.py -=================================================================== ---- numba-0.59.1.orig/numba/tests/test_mathlib.py -+++ numba-0.59.1/numba/tests/test_mathlib.py -@@ -508,6 +508,7 @@ class TestMathLib(TestCase): +--- a/numba/tests/test_mathlib.py ++++ b/numba/tests/test_mathlib.py +@@ -543,6 +543,7 @@ class TestMathLib(TestCase): float('-inf'), float('inf'), float('nan')] self.run_unary(pyfunc, x_types, x_values, prec='exact') @@ -69,3 +25,41 @@ Index: numba-0.59.1/numba/tests/test_mathlib.py def test_ldexp(self): pyfunc = ldexp cfunc = njit(pyfunc) +--- a/numba/tests/test_parfors.py ++++ b/numba/tests/test_parfors.py +@@ -1205,6 +1205,7 @@ class TestParforNumPy(TestParforsBase): + self.check_variants(test_impl2, data_gen) + self.count_parfors_variants(test_impl2, data_gen) + ++ @unittest.skip("Fails on type check in OBS") + def test_ndarray_fill(self): + def test_impl(x): + x.fill(7.0) +@@ -4725,7 +4726,7 @@ class TestParforsVectorizer(TestPrangeBa + + return asm + +- @linux_only ++ @unittest.skip("Our x86_64 asm is most probably different from the upstream one.") + @TestCase.run_test_in_subprocess + def test_vectorizer_fastmath_asm(self): + """ This checks that if fastmath is set and the underlying hardware +@@ -4766,7 +4767,7 @@ class TestParforsVectorizer(TestPrangeBa + # check no zmm addressing is present + self.assertTrue('zmm' not in v) + +- @linux_only ++ @unittest.skip("Our x86_64 asm is most probably different from the upstream one.") + @TestCase.run_test_in_subprocess(envvars={'NUMBA_BOUNDSCHECK': '0'}) + def test_unsigned_refusal_to_vectorize(self): + """ This checks that if fastmath is set and the underlying hardware +--- a/numba/tests/test_parfors_passes.py ++++ b/numba/tests/test_parfors_passes.py +@@ -514,6 +514,7 @@ class TestConvertLoopPass(BaseTest): + str(raises.exception), + ) + ++ @unittest.skip("Fails on type check in OBS") + def test_init_prange(self): + def test_impl(): + n = 20