diff --git a/numba/__init__.py b/numba/__init__.py index 33f752018..7d3b3ae8d 100644 --- a/numba/__init__.py +++ b/numba/__init__.py @@ -39,8 +39,8 @@ def _ensure_critical_deps(): f"{numpy_version[0]}.{numpy_version[1]}.") raise ImportError(msg) - if numpy_version > (2, 3): - msg = (f"Numba needs NumPy 2.3 or less. Got NumPy " + if numpy_version > (2, 4): + msg = (f"Numba needs NumPy 2.4 or less. Got NumPy " f"{numpy_version[0]}.{numpy_version[1]}.") raise ImportError(msg) diff --git a/numba/np/arraymath.py b/numba/np/arraymath.py index 6b031d789..75e9869a1 100644 --- a/numba/np/arraymath.py +++ b/numba/np/arraymath.py @@ -2222,7 +2222,7 @@ def get_d_impl(x, dx): return impl -@overload(np.trapz) +@overload(np.trapezoid) def np_trapz(y, x=None, dx=1.0): if isinstance(y, (types.Number, types.Boolean)): @@ -4941,12 +4941,12 @@ def jit_np_setdiff1d(ar1, ar2, assume_unique=False): else: ar1 = np.unique(ar1) ar2 = np.unique(ar2) - return ar1[np.in1d(ar1, ar2, assume_unique=True, invert=True)] + return ar1[np.isin(ar1, ar2, assume_unique=True, invert=True)] return np_setdiff1d_impl -@overload(np.in1d) +@overload(np.isin) def jit_np_in1d(ar1, ar2, assume_unique=False, invert=False): if not (type_can_asarray(ar1) or type_can_asarray(ar2)): raise TypingError('in1d: first two args must be array-like') @@ -4958,6 +4958,8 @@ def jit_np_in1d(ar1, ar2, assume_unique=False, invert=False): def np_in1d_impl(ar1, ar2, assume_unique=False, invert=False): # https://github.com/numpy/numpy/blob/03b62604eead0f7d279a5a4c094743eb29647368/numpy/lib/arraysetops.py#L525 # noqa: E501 + ar1 = np.asarray(ar1) + shape = ar1.shape # Ravel both arrays, behavior for the first array could be different ar1 = np.asarray(ar1).ravel() ar2 = np.asarray(ar2).ravel() @@ -4974,7 +4976,7 @@ def jit_np_in1d(ar1, ar2, assume_unique=False, invert=False): mask = np.zeros(len(ar1), dtype=np.bool_) for a in ar2: mask |= (ar1 == a) - return mask + return mask.reshape(shape) # Otherwise use sorting if not assume_unique: @@ -5008,27 +5010,8 @@ def jit_np_in1d(ar1, ar2, assume_unique=False, invert=False): # return ret[:len(ar1)] if assume_unique: - return ret[:len(ar1)] + return ret[:len(ar1)].reshape(shape) else: - return ret[inv_idx] + return ret[inv_idx].reshape(shape) return np_in1d_impl - - -@overload(np.isin) -def jit_np_isin(element, test_elements, assume_unique=False, invert=False): - if not (type_can_asarray(element) or type_can_asarray(test_elements)): - raise TypingError('isin: first two args must be array-like') - if not (isinstance(assume_unique, (types.Boolean, bool))): - raise TypingError('isin: Argument "assume_unique" must be boolean') - if not (isinstance(invert, (types.Boolean, bool))): - raise TypingError('isin: Argument "invert" must be boolean') - - # https://github.com/numpy/numpy/blob/03b62604eead0f7d279a5a4c094743eb29647368/numpy/lib/arraysetops.py#L889 # noqa: E501 - def np_isin_impl(element, test_elements, assume_unique=False, invert=False): - - element = np.asarray(element) - return np.in1d(element, test_elements, assume_unique=assume_unique, - invert=invert).reshape(element.shape) - - return np_isin_impl diff --git a/numba/tests/test_exceptions.py b/numba/tests/test_exceptions.py index e6855c4ff..71c913963 100644 --- a/numba/tests/test_exceptions.py +++ b/numba/tests/test_exceptions.py @@ -189,7 +189,7 @@ class TestRaising(TestCase): self.check_against_python(flags, pyfunc, cfunc, MyError, 1) self.check_against_python(flags, pyfunc, cfunc, ValueError, 2) self.check_against_python(flags, pyfunc, cfunc, - np.linalg.linalg.LinAlgError, 3) + np.linalg.LinAlgError, 3) def test_raise_class_nopython(self): self.check_raise_class(flags=no_pyobj_flags) @@ -207,7 +207,7 @@ class TestRaising(TestCase): self.check_against_python(flags, pyfunc, cfunc, clazz, 1) self.check_against_python(flags, pyfunc, cfunc, ValueError, 2) self.check_against_python(flags, pyfunc, cfunc, - np.linalg.linalg.LinAlgError, 3) + np.linalg.LinAlgError, 3) def test_raise_instance_objmode(self): self.check_raise_instance(flags=force_pyobj_flags) @@ -374,7 +374,7 @@ class TestRaising(TestCase): self.check_against_python(flags, pyfunc, cfunc, ValueError, 2, 'world') self.check_against_python(flags, pyfunc, cfunc, - np.linalg.linalg.LinAlgError, 3, 'linalg') + np.linalg.LinAlgError, 3, 'linalg') def test_raise_instance_with_runtime_args_objmode(self): self.check_raise_instance_with_runtime_args(flags=force_pyobj_flags) diff --git a/numba/tests/test_extending.py b/numba/tests/test_extending.py index f8608a6e6..86a4d177e 100644 --- a/numba/tests/test_extending.py +++ b/numba/tests/test_extending.py @@ -2124,7 +2124,7 @@ class TestNumbaInternalOverloads(TestCase): # 1 to get violations reported to STDOUT # 2 to get a verbose output of everything that was checked and its state # reported to STDOUT. - DEBUG = 0 + DEBUG = 1 # np.random.* does not have a signature exposed to `inspect`... so # custom parse the docstrings. diff --git a/numba/tests/test_np_functions.py b/numba/tests/test_np_functions.py index f76b3ff9c..5a6449529 100644 --- a/numba/tests/test_np_functions.py +++ b/numba/tests/test_np_functions.py @@ -347,19 +347,19 @@ def extract(condition, arr): def np_trapz(y): - return np.trapz(y) + return np.trapezoid(y) def np_trapz_x(y, x): - return np.trapz(y, x) + return np.trapezoid(y, x) def np_trapz_dx(y, dx): - return np.trapz(y, dx=dx) + return np.trapezoid(y, dx=dx) def np_trapz_x_dx(y, x, dx): - return np.trapz(y, x, dx) + return np.trapezoid(y, x, dx) def np_trapezoid(y): @@ -510,22 +510,6 @@ def np_setdiff1d_3(a, b, assume_unique=False): return np.setdiff1d(a, b, assume_unique) -def np_in1d_2(a, b): - return np.in1d(a, b) - - -def np_in1d_3a(a, b, assume_unique=False): - return np.in1d(a, b, assume_unique=assume_unique) - - -def np_in1d_3b(a, b, invert=False): - return np.in1d(a, b, invert=invert) - - -def np_in1d_4(a, b, assume_unique=False, invert=False): - return np.in1d(a, b, assume_unique, invert) - - def np_isin_2(a, b): return np.isin(a, b) @@ -6634,122 +6618,6 @@ class TestNPFunctions(MemoryLeakMixin, TestCase): with self.assertRaises(TypingError): np_nbfunc(a, "foo", True) - @staticmethod - def _in1d_arrays(): - yield (List.empty_list(types.float64), - List.empty_list(types.float64)) # two empty arrays - yield [1], List.empty_list(types.float64) # empty right - yield List.empty_list(types.float64), [1] # empty left - yield [1], [2] # singletons - False - yield [1], [1] # singletons - True - yield [1, 2], [1] - yield [1, 2, 2], [2, 2] - yield [1, 2, 2], [2, 2, 3] - yield [1, 2], [2, 1] - yield [1, 2, 3], [1, 2, 3] - yield [2, 3, 4, 0], [3, 1] - yield [2, 3], np.arange(20) # Test the "sorting" method. - yield [2, 3], np.tile(np.arange(5), 4) - - def test_in1d_2(self): - np_pyfunc = np_in1d_2 - np_nbfunc = njit(np_pyfunc) - - def check(ar1, ar2): - if isinstance(ar1, list): - ar1 = List(ar1) - if isinstance(ar2, list): - ar2 = List(ar2) - expected = np_pyfunc(ar1, ar2) - got = np_nbfunc(ar1, ar2) - self.assertPreciseEqual(expected, got, msg=f"ar1={ar1}, ar2={ar2}") - - for a, b in self._in1d_arrays(): - check(a, b) - - def test_in1d_3a(self): - np_pyfunc = np_in1d_3a - np_nbfunc = njit(np_pyfunc) - - def check(ar1, ar2, assume_unique=False): - if isinstance(ar1, list): - ar1 = List(ar1) - if isinstance(ar2, list): - ar2 = List(ar2) - expected = np_pyfunc(ar1, ar2, assume_unique) - got = np_nbfunc(ar1, ar2, assume_unique) - self.assertPreciseEqual(expected, got, msg=f"ar1={ar1}, ar2={ar2}") - - for a, b in self._in1d_arrays(): - check(a, b) - if len(np.unique(a)) == len(a) and len(np.unique(b)) == len(b): - check(a, b, assume_unique=True) - - def test_in1d_3b(self): - np_pyfunc = np_in1d_3b - np_nbfunc = njit(np_pyfunc) - - def check(ar1, ar2, invert=False): - if isinstance(ar1, list): - ar1 = List(ar1) - if isinstance(ar2, list): - ar2 = List(ar2) - expected = np_pyfunc(ar1, ar2, invert) - got = np_nbfunc(ar1, ar2, invert) - self.assertPreciseEqual(expected, got, msg=f"ar1={ar1}, ar2={ar2}") - - for a, b in self._in1d_arrays(): - check(a, b, invert=False) - check(a, b, invert=True) - - def test_in1d_4(self): - np_pyfunc = np_in1d_4 - np_nbfunc = njit(np_pyfunc) - - def check(ar1, ar2, assume_unique=False, invert=False): - if isinstance(ar1, list): - ar1 = List(ar1) - if isinstance(ar2, list): - ar2 = List(ar2) - expected = np_pyfunc(ar1, ar2, assume_unique, invert) - got = np_nbfunc(ar1, ar2, assume_unique, invert) - self.assertPreciseEqual(expected, got, msg=f"ar1={ar1}, ar2={ar2}") - - for a, b in self._in1d_arrays(): - check(a, b, invert=False) - check(a, b, invert=True) - if len(np.unique(a)) == len(a) and len(np.unique(b)) == len(b): - check(a, b, assume_unique=True, invert=False) - check(a, b, assume_unique=True, invert=True) - - def test_in1d_errors(self): - np_pyfunc = np_in1d_4 - np_nbfunc = njit(np_pyfunc) - - a = np.array([1]) - b = np.array([2]) - x = np_nbfunc(a, b) - self.assertPreciseEqual(x, np.array([False])) - - self.disable_leak_check() - with self.assertRaises(TypingError): - np_nbfunc(a, b, "foo", False) - with self.assertRaises(TypingError): - np_nbfunc(a, b, False, "foo") - with self.assertRaises(TypingError): - np_nbfunc("foo", b, True, False) - with self.assertRaises(TypingError): - np_nbfunc(a, "foo", True, False) - - @njit() - def np_in1d_kind(a, b, kind): - return np.in1d(a, b, kind=kind) - - with self.assertRaises(TypingError): - np_in1d_kind(a, b, kind=None) - with self.assertRaises(TypingError): - np_in1d_kind(a, b, kind="table") - @classmethod def _isin_arrays(cls): if REDUCED_TESTING: diff --git a/setup.py b/setup.py index 9eaa191cb..a5febef1e 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ min_python_version = "3.10" max_python_version = "3.15" # exclusive min_numpy_build_version = "2.0.0rc1" min_numpy_run_version = "1.22" -max_numpy_run_version = "2.4" +max_numpy_run_version = "2.5" min_llvmlite_version = "0.46.0dev0" max_llvmlite_version = "0.47"