diff --git a/.github/workflows/array-api-tests.yml b/.github/workflows/array-api-tests.yml index 9f168cb..4386cde 100644 --- a/.github/workflows/array-api-tests.yml +++ b/.github/workflows/array-api-tests.yml @@ -11,11 +11,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] - numpy-version: ['1.26', 'dev'] - exclude: - - python-version: '3.8' - numpy-version: 'dev' + python-version: ['3.10', '3.11', '3.12'] + numpy-version: ['2.1', 'dev'] steps: - name: Checkout array-api-strict @@ -38,7 +35,7 @@ jobs: if [[ "${{ matrix.numpy-version }}" == "dev" ]]; then python -m pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy; else - python -m pip install 'numpy>=1.26,<2.0'; + python -m pip install 'numpy>=${{ matrix.numpy-version }},<${{ matrix.numpy-version }}.99'; fi python -m pip install ${GITHUB_WORKSPACE}/array-api-strict python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d8124d4..a03c045 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,11 +5,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] - numpy-version: ['1.26', 'dev'] - exclude: - - python-version: '3.8' - numpy-version: 'dev' + python-version: ['3.10', '3.11', '3.12'] + numpy-version: ['2.1', 'dev'] fail-fast: true steps: - uses: actions/checkout@v4 @@ -22,7 +19,7 @@ jobs: if [[ "${{ matrix.numpy-version }}" == "dev" ]]; then python -m pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy; else - python -m pip install 'numpy>=1.26,<2.0'; + python -m pip install 'numpy>=${{ matrix.numpy-version }},<${{ matrix.numpy-version }}.99'; fi python -m pip install -r requirements-dev.txt - name: Run Tests diff --git a/array_api_strict/__init__.py b/array_api_strict/__init__.py index ff43660..cbda499 100644 --- a/array_api_strict/__init__.py +++ b/array_api_strict/__init__.py @@ -16,6 +16,12 @@ """ +import numpy as np +from numpy.lib import NumpyVersion + +if NumpyVersion(np.__version__) < NumpyVersion('2.1.0'): + raise ImportError("array-api-strict requires NumPy >= 2.1.0") + __all__ = [] # Warning: __array_api_version__ could change globally with diff --git a/array_api_strict/_array_object.py b/array_api_strict/_array_object.py index 53669d1..76cdfac 100644 --- a/array_api_strict/_array_object.py +++ b/array_api_strict/_array_object.py @@ -162,19 +162,7 @@ def __array__(self, dtype: None | np.dtype[Any] = None, copy: None | bool = None if _allow_array: if self._device != CPU_DEVICE: raise RuntimeError(f"Can not convert array on the '{self._device}' device to a Numpy array.") - # copy keyword is new in 2.0.0; for older versions don't use it - # retry without that keyword. - if np.__version__[0] < '2': - return np.asarray(self._array, dtype=dtype) - elif np.__version__.startswith('2.0.0-dev0'): - # Handle dev version for which we can't know based on version - # number whether or not the copy keyword is supported. - try: - return np.asarray(self._array, dtype=dtype, copy=copy) - except TypeError: - return np.asarray(self._array, dtype=dtype) - else: - return np.asarray(self._array, dtype=dtype, copy=copy) + return np.asarray(self._array, dtype=dtype, copy=copy) raise ValueError("Conversion from an array_api_strict array to a NumPy ndarray is not supported") # These are various helper functions to make the array behavior match the @@ -586,24 +574,14 @@ def __dlpack__( if copy is not _default: raise ValueError("The copy argument to __dlpack__ requires at least version 2023.12 of the array API") - if np.__version__[0] < '2.1': - if max_version not in [_default, None]: - raise NotImplementedError("The max_version argument to __dlpack__ is not yet implemented") - if dl_device not in [_default, None]: - raise NotImplementedError("The device argument to __dlpack__ is not yet implemented") - if copy not in [_default, None]: - raise NotImplementedError("The copy argument to __dlpack__ is not yet implemented") - - return self._array.__dlpack__(stream=stream) - else: - kwargs = {'stream': stream} - if max_version is not _default: - kwargs['max_version'] = max_version - if dl_device is not _default: - kwargs['dl_device'] = dl_device - if copy is not _default: - kwargs['copy'] = copy - return self._array.__dlpack__(**kwargs) + kwargs = {'stream': stream} + if max_version is not _default: + kwargs['max_version'] = max_version + if dl_device is not _default: + kwargs['dl_device'] = dl_device + if copy is not _default: + kwargs['copy'] = copy + return self._array.__dlpack__(**kwargs) def __dlpack_device__(self: Array, /) -> Tuple[IntEnum, int]: """ diff --git a/array_api_strict/_creation_functions.py b/array_api_strict/_creation_functions.py index d6d3efa..8d7705b 100644 --- a/array_api_strict/_creation_functions.py +++ b/array_api_strict/_creation_functions.py @@ -83,29 +83,6 @@ def asarray( if isinstance(obj, Array) and device is None: device = obj.device - if np.__version__[0] < '2': - if copy is False: - # Note: copy=False is not yet implemented in np.asarray for - # NumPy 1 - - # Work around it by creating the new array and seeing if NumPy - # copies it. - if isinstance(obj, Array): - new_array = np.array(obj._array, copy=copy, dtype=_np_dtype) - if new_array is not obj._array: - raise ValueError("Unable to avoid copy while creating an array from given array.") - return Array._new(new_array, device=device) - elif _supports_buffer_protocol(obj): - # Buffer protocol will always support no-copy - return Array._new(np.array(obj, copy=copy, dtype=_np_dtype), device=device) - else: - # No-copy is unsupported for Python built-in types. - raise ValueError("Unable to avoid copy while creating an array from given object.") - - if copy is None: - # NumPy 1 treats copy=False the same as the standard copy=None - copy = False - if isinstance(obj, Array): return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype), device=device) if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)): diff --git a/array_api_strict/tests/test_array_object.py b/array_api_strict/tests/test_array_object.py index 96fd31e..0480f00 100644 --- a/array_api_strict/tests/test_array_object.py +++ b/array_api_strict/tests/test_array_object.py @@ -456,31 +456,19 @@ def dlpack_2023_12(api_version): set_array_api_strict_flags(api_version=api_version) a = asarray([1, 2, 3], dtype=int8) - # Never an error - a.__dlpack__() - - if np.__version__ < '2.1': - exception = NotImplementedError if api_version >= '2023.12' else ValueError - pytest.raises(exception, lambda: - a.__dlpack__(dl_device=CPU_DEVICE)) - pytest.raises(exception, lambda: - a.__dlpack__(dl_device=None)) - pytest.raises(exception, lambda: - a.__dlpack__(max_version=(1, 0))) - pytest.raises(exception, lambda: - a.__dlpack__(max_version=None)) - pytest.raises(exception, lambda: - a.__dlpack__(copy=False)) - pytest.raises(exception, lambda: - a.__dlpack__(copy=True)) - pytest.raises(exception, lambda: - a.__dlpack__(copy=None)) - else: - a.__dlpack__(dl_device=CPU_DEVICE) - a.__dlpack__(dl_device=None) - a.__dlpack__(max_version=(1, 0)) - a.__dlpack__(max_version=None) - a.__dlpack__(copy=False) - a.__dlpack__(copy=True) - a.__dlpack__(copy=None) + # Do not error + a.__dlpack__() + a.__dlpack__(dl_device=CPU_DEVICE) + a.__dlpack__(dl_device=None) + a.__dlpack__(max_version=(1, 0)) + a.__dlpack__(max_version=None) + a.__dlpack__(copy=False) + a.__dlpack__(copy=True) + a.__dlpack__(copy=None) + + x = np.from_dlpack(a) + assert isinstance(x, np.ndarray) + assert x.dtype == np.int8 + assert x.shape == (3,) + assert np.all(x == np.asarray([1, 2, 3])) diff --git a/requirements-dev.txt b/requirements-dev.txt index 137e973..62673a8 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,3 @@ pytest hypothesis -numpy +numpy>=2.1 diff --git a/requirements.txt b/requirements.txt index 24ce15a..92ce2ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -numpy +numpy>=2.1 diff --git a/setup.py b/setup.py index 29a94df..89e85e5 100644 --- a/setup.py +++ b/setup.py @@ -15,14 +15,15 @@ long_description_content_type="text/markdown", url="https://data-apis.org/array-api-strict/", license="MIT", - python_requires=">=3.9", - install_requires=["numpy"], + python_requires=">=3.10", + install_requires=["numpy>=2.1"], classifiers=[ "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", ],