Skip to content

Commit 4e5ff09

Browse files
authored
Merge pull request data-apis#90 from data-apis/revert-87-require-numpy-2
Revert "Require NumPy >= 2.1"
2 parents 206baf0 + b20f8b4 commit 4e5ff09

File tree

9 files changed

+109
-43
lines changed

9 files changed

+109
-43
lines changed

.github/workflows/array-api-tests.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ jobs:
1111
runs-on: ubuntu-latest
1212
strategy:
1313
matrix:
14-
python-version: ['3.10', '3.11', '3.12']
15-
numpy-version: ['2.1', 'dev']
14+
python-version: ['3.9', '3.10', '3.11', '3.12']
15+
numpy-version: ['1.26', 'dev']
16+
exclude:
17+
- python-version: '3.8'
18+
numpy-version: 'dev'
1619

1720
steps:
1821
- name: Checkout array-api-strict
@@ -35,7 +38,7 @@ jobs:
3538
if [[ "${{ matrix.numpy-version }}" == "dev" ]]; then
3639
python -m pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy;
3740
else
38-
python -m pip install 'numpy>=${{ matrix.numpy-version }},<${{ matrix.numpy-version }}.99';
41+
python -m pip install 'numpy>=1.26,<2.0';
3942
fi
4043
python -m pip install ${GITHUB_WORKSPACE}/array-api-strict
4144
python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt

.github/workflows/tests.yml

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ jobs:
55
runs-on: ubuntu-latest
66
strategy:
77
matrix:
8-
python-version: ['3.10', '3.11', '3.12']
9-
numpy-version: ['2.1', 'dev']
8+
python-version: ['3.9', '3.10', '3.11', '3.12']
9+
numpy-version: ['1.26', 'dev']
10+
exclude:
11+
- python-version: '3.8'
12+
numpy-version: 'dev'
1013
fail-fast: true
1114
steps:
1215
- uses: actions/checkout@v4
@@ -19,7 +22,7 @@ jobs:
1922
if [[ "${{ matrix.numpy-version }}" == "dev" ]]; then
2023
python -m pip install --pre --extra-index https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy;
2124
else
22-
python -m pip install 'numpy>=${{ matrix.numpy-version }},<${{ matrix.numpy-version }}.99';
25+
python -m pip install 'numpy>=1.26,<2.0';
2326
fi
2427
python -m pip install -r requirements-dev.txt
2528
- name: Run Tests

array_api_strict/__init__.py

-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@
1616
1717
"""
1818

19-
import numpy as np
20-
from numpy.lib import NumpyVersion
21-
22-
if NumpyVersion(np.__version__) < NumpyVersion('2.1.0'):
23-
raise ImportError("array-api-strict requires NumPy >= 2.1.0")
24-
2519
__all__ = []
2620

2721
# Warning: __array_api_version__ could change globally with

array_api_strict/_array_object.py

+31-9
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,19 @@ def __array__(self, dtype: None | np.dtype[Any] = None, copy: None | bool = None
162162
if _allow_array:
163163
if self._device != CPU_DEVICE:
164164
raise RuntimeError(f"Can not convert array on the '{self._device}' device to a Numpy array.")
165-
return np.asarray(self._array, dtype=dtype, copy=copy)
165+
# copy keyword is new in 2.0.0; for older versions don't use it
166+
# retry without that keyword.
167+
if np.__version__[0] < '2':
168+
return np.asarray(self._array, dtype=dtype)
169+
elif np.__version__.startswith('2.0.0-dev0'):
170+
# Handle dev version for which we can't know based on version
171+
# number whether or not the copy keyword is supported.
172+
try:
173+
return np.asarray(self._array, dtype=dtype, copy=copy)
174+
except TypeError:
175+
return np.asarray(self._array, dtype=dtype)
176+
else:
177+
return np.asarray(self._array, dtype=dtype, copy=copy)
166178
raise ValueError("Conversion from an array_api_strict array to a NumPy ndarray is not supported")
167179

168180
# These are various helper functions to make the array behavior match the
@@ -574,14 +586,24 @@ def __dlpack__(
574586
if copy is not _default:
575587
raise ValueError("The copy argument to __dlpack__ requires at least version 2023.12 of the array API")
576588

577-
kwargs = {'stream': stream}
578-
if max_version is not _default:
579-
kwargs['max_version'] = max_version
580-
if dl_device is not _default:
581-
kwargs['dl_device'] = dl_device
582-
if copy is not _default:
583-
kwargs['copy'] = copy
584-
return self._array.__dlpack__(**kwargs)
589+
if np.lib.NumpyVersion(np.__version__) < '2.1.0':
590+
if max_version not in [_default, None]:
591+
raise NotImplementedError("The max_version argument to __dlpack__ is not yet implemented")
592+
if dl_device not in [_default, None]:
593+
raise NotImplementedError("The device argument to __dlpack__ is not yet implemented")
594+
if copy not in [_default, None]:
595+
raise NotImplementedError("The copy argument to __dlpack__ is not yet implemented")
596+
597+
return self._array.__dlpack__(stream=stream)
598+
else:
599+
kwargs = {'stream': stream}
600+
if max_version is not _default:
601+
kwargs['max_version'] = max_version
602+
if dl_device is not _default:
603+
kwargs['dl_device'] = dl_device
604+
if copy is not _default:
605+
kwargs['copy'] = copy
606+
return self._array.__dlpack__(**kwargs)
585607

586608
def __dlpack_device__(self: Array, /) -> Tuple[IntEnum, int]:
587609
"""

array_api_strict/_creation_functions.py

+23
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,29 @@ def asarray(
8383
if isinstance(obj, Array) and device is None:
8484
device = obj.device
8585

86+
if np.lib.NumpyVersion(np.__version__) < '2.0.0':
87+
if copy is False:
88+
# Note: copy=False is not yet implemented in np.asarray for
89+
# NumPy 1
90+
91+
# Work around it by creating the new array and seeing if NumPy
92+
# copies it.
93+
if isinstance(obj, Array):
94+
new_array = np.array(obj._array, copy=copy, dtype=_np_dtype)
95+
if new_array is not obj._array:
96+
raise ValueError("Unable to avoid copy while creating an array from given array.")
97+
return Array._new(new_array, device=device)
98+
elif _supports_buffer_protocol(obj):
99+
# Buffer protocol will always support no-copy
100+
return Array._new(np.array(obj, copy=copy, dtype=_np_dtype), device=device)
101+
else:
102+
# No-copy is unsupported for Python built-in types.
103+
raise ValueError("Unable to avoid copy while creating an array from given object.")
104+
105+
if copy is None:
106+
# NumPy 1 treats copy=False the same as the standard copy=None
107+
copy = False
108+
86109
if isinstance(obj, Array):
87110
return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype), device=device)
88111
if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)):

array_api_strict/tests/test_array_object.py

+38-16
Original file line numberDiff line numberDiff line change
@@ -448,27 +448,49 @@ def test_iter():
448448
pytest.raises(TypeError, lambda: iter(ones((3, 3))))
449449

450450
@pytest.mark.parametrize("api_version", ['2021.12', '2022.12', '2023.12'])
451-
def dlpack_2023_12(api_version):
451+
def test_dlpack_2023_12(api_version):
452452
if api_version == '2021.12':
453453
with pytest.warns(UserWarning):
454454
set_array_api_strict_flags(api_version=api_version)
455455
else:
456456
set_array_api_strict_flags(api_version=api_version)
457457

458458
a = asarray([1, 2, 3], dtype=int8)
459-
460-
# Do not error
459+
# Never an error
461460
a.__dlpack__()
462-
a.__dlpack__(dl_device=CPU_DEVICE)
463-
a.__dlpack__(dl_device=None)
464-
a.__dlpack__(max_version=(1, 0))
465-
a.__dlpack__(max_version=None)
466-
a.__dlpack__(copy=False)
467-
a.__dlpack__(copy=True)
468-
a.__dlpack__(copy=None)
469-
470-
x = np.from_dlpack(a)
471-
assert isinstance(x, np.ndarray)
472-
assert x.dtype == np.int8
473-
assert x.shape == (3,)
474-
assert np.all(x == np.asarray([1, 2, 3]))
461+
462+
if api_version < '2023.12':
463+
pytest.raises(ValueError, lambda:
464+
a.__dlpack__(dl_device=a.__dlpack_device__()))
465+
pytest.raises(ValueError, lambda:
466+
a.__dlpack__(dl_device=None))
467+
pytest.raises(ValueError, lambda:
468+
a.__dlpack__(max_version=(1, 0)))
469+
pytest.raises(ValueError, lambda:
470+
a.__dlpack__(max_version=None))
471+
pytest.raises(ValueError, lambda:
472+
a.__dlpack__(copy=False))
473+
pytest.raises(ValueError, lambda:
474+
a.__dlpack__(copy=True))
475+
pytest.raises(ValueError, lambda:
476+
a.__dlpack__(copy=None))
477+
elif np.lib.NumpyVersion(np.__version__) < '2.1.0':
478+
pytest.raises(NotImplementedError, lambda:
479+
a.__dlpack__(dl_device=CPU_DEVICE))
480+
a.__dlpack__(dl_device=None)
481+
pytest.raises(NotImplementedError, lambda:
482+
a.__dlpack__(max_version=(1, 0)))
483+
a.__dlpack__(max_version=None)
484+
pytest.raises(NotImplementedError, lambda:
485+
a.__dlpack__(copy=False))
486+
pytest.raises(NotImplementedError, lambda:
487+
a.__dlpack__(copy=True))
488+
a.__dlpack__(copy=None)
489+
else:
490+
a.__dlpack__(dl_device=a.__dlpack_device__())
491+
a.__dlpack__(dl_device=None)
492+
a.__dlpack__(max_version=(1, 0))
493+
a.__dlpack__(max_version=None)
494+
a.__dlpack__(copy=False)
495+
a.__dlpack__(copy=True)
496+
a.__dlpack__(copy=None)

requirements-dev.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pytest
22
hypothesis
3-
numpy>=2.1
3+
numpy

requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
numpy>=2.1
1+
numpy

setup.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@
1515
long_description_content_type="text/markdown",
1616
url="https://data-apis.org/array-api-strict/",
1717
license="MIT",
18-
python_requires=">=3.10",
19-
install_requires=["numpy>=2.1"],
18+
python_requires=">=3.9",
19+
install_requires=["numpy"],
2020
classifiers=[
2121
"Programming Language :: Python :: 3",
22+
"Programming Language :: Python :: 3.9",
2223
"Programming Language :: Python :: 3.10",
2324
"Programming Language :: Python :: 3.11",
2425
"Programming Language :: Python :: 3.12",
25-
"Programming Language :: Python :: 3.13",
26-
"Intended Audience :: Developers",
2726
"License :: OSI Approved :: BSD License",
2827
"Operating System :: OS Independent",
2928
],

0 commit comments

Comments
 (0)