array-api-strict 2.4__tar.gz → 2.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/array-api-tests.yml +9 -5
  2. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/docs-deploy.yml +1 -1
  3. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/tests.yml +6 -2
  4. {array_api_strict-2.4 → array_api_strict-2.4.1}/CHANGELOG.md +28 -2
  5. {array_api_strict-2.4/array_api_strict.egg-info → array_api_strict-2.4.1}/PKG-INFO +1 -1
  6. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_array_object.py +46 -18
  7. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_version.py +2 -2
  8. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_array_object.py +68 -18
  9. {array_api_strict-2.4 → array_api_strict-2.4.1/array_api_strict.egg-info}/PKG-INFO +1 -1
  10. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/changelog.md +28 -2
  11. {array_api_strict-2.4 → array_api_strict-2.4.1}/.gitattributes +0 -0
  12. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/dependabot.yml +0 -0
  13. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/dependabot-auto-merge.yml +0 -0
  14. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/docs-build.yml +0 -0
  15. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/publish-package.yml +0 -0
  16. {array_api_strict-2.4 → array_api_strict-2.4.1}/.github/workflows/ruff.yml +0 -0
  17. {array_api_strict-2.4 → array_api_strict-2.4.1}/.gitignore +0 -0
  18. {array_api_strict-2.4 → array_api_strict-2.4.1}/LICENSE +0 -0
  19. {array_api_strict-2.4 → array_api_strict-2.4.1}/README.md +0 -0
  20. {array_api_strict-2.4 → array_api_strict-2.4.1}/array-api-tests-xfails.txt +0 -0
  21. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/__init__.py +0 -0
  22. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_constants.py +0 -0
  23. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_creation_functions.py +0 -0
  24. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_data_type_functions.py +0 -0
  25. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_dtypes.py +0 -0
  26. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_elementwise_functions.py +0 -0
  27. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_fft.py +0 -0
  28. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_flags.py +0 -0
  29. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_helpers.py +0 -0
  30. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_indexing_functions.py +0 -0
  31. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_info.py +0 -0
  32. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_linalg.py +0 -0
  33. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_linear_algebra_functions.py +0 -0
  34. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_manipulation_functions.py +0 -0
  35. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_searching_functions.py +0 -0
  36. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_set_functions.py +0 -0
  37. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_sorting_functions.py +0 -0
  38. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_statistical_functions.py +0 -0
  39. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_typing.py +0 -0
  40. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/_utility_functions.py +0 -0
  41. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/py.typed +0 -0
  42. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/__init__.py +0 -0
  43. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/conftest.py +0 -0
  44. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_creation_functions.py +0 -0
  45. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_data_type_functions.py +0 -0
  46. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_device_support.py +0 -0
  47. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_elementwise_functions.py +0 -0
  48. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_flags.py +0 -0
  49. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_indexing_functions.py +0 -0
  50. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_linalg.py +0 -0
  51. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_manipulation_functions.py +0 -0
  52. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_searching_functions.py +0 -0
  53. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_set_functions.py +0 -0
  54. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_sorting_functions.py +0 -0
  55. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_statistical_functions.py +0 -0
  56. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict/tests/test_validation.py +0 -0
  57. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict.egg-info/SOURCES.txt +0 -0
  58. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict.egg-info/dependency_links.txt +0 -0
  59. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict.egg-info/requires.txt +0 -0
  60. {array_api_strict-2.4 → array_api_strict-2.4.1}/array_api_strict.egg-info/top_level.txt +0 -0
  61. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/Makefile +0 -0
  62. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/_static/custom.css +0 -0
  63. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/_static/favicon.png +0 -0
  64. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/api.rst +0 -0
  65. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/conf.py +0 -0
  66. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/index.md +0 -0
  67. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/make.bat +0 -0
  68. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/releasing.md +0 -0
  69. {array_api_strict-2.4 → array_api_strict-2.4.1}/docs/requirements.txt +0 -0
  70. {array_api_strict-2.4 → array_api_strict-2.4.1}/pyproject.toml +0 -0
  71. {array_api_strict-2.4 → array_api_strict-2.4.1}/pytest.ini +0 -0
  72. {array_api_strict-2.4 → array_api_strict-2.4.1}/requirements-dev.txt +0 -0
  73. {array_api_strict-2.4 → array_api_strict-2.4.1}/requirements.txt +0 -0
  74. {array_api_strict-2.4 → array_api_strict-2.4.1}/ruff.toml +0 -0
  75. {array_api_strict-2.4 → array_api_strict-2.4.1}/setup.cfg +0 -0
@@ -3,7 +3,7 @@ name: Array API Tests
3
3
  on: [push, pull_request]
4
4
 
5
5
  env:
6
- PYTEST_ARGS: "-v -rxXfE --hypothesis-disable-deadline --max-examples 200"
6
+ PYTEST_ARGS: "-v -rxXfE --hypothesis-disable-deadline --max-examples 500 -n 4"
7
7
  API_VERSIONS: "2023.12 2024.12"
8
8
 
9
9
  jobs:
@@ -11,12 +11,16 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- python-version: ['3.12', '3.13']
15
- numpy-version: ['1.26', '2.2', 'dev']
14
+ python-version: ['3.10', '3.11', '3.12', '3.13']
15
+ numpy-version: ['1.26', '2.3', 'dev']
16
16
  exclude:
17
+ - python-version: '3.10'
18
+ numpy-version: '2.3'
19
+ - python-version: '3.10'
20
+ numpy-version: 'dev'
17
21
  - python-version: '3.13'
18
22
  numpy-version: '1.26'
19
-
23
+ fail-fast: false
20
24
  steps:
21
25
  - name: Checkout array-api-strict
22
26
  uses: actions/checkout@v4
@@ -42,7 +46,7 @@ jobs:
42
46
  fi
43
47
  python -m pip install ${GITHUB_WORKSPACE}/array-api-strict
44
48
  python -m pip install -r ${GITHUB_WORKSPACE}/array-api-tests/requirements.txt
45
- python -m pip install hypothesis
49
+ python -m pip install hypothesis pytest-xdist
46
50
  - name: Run the array API testsuite
47
51
  env:
48
52
  ARRAY_API_TESTS_MODULE: array_api_strict
@@ -13,7 +13,7 @@ jobs:
13
13
  steps:
14
14
  - uses: actions/checkout@v4
15
15
  - name: Download Artifact
16
- uses: dawidd6/action-download-artifact@v10
16
+ uses: dawidd6/action-download-artifact@v11
17
17
  with:
18
18
  workflow: docs-build.yml
19
19
  name: docs-build
@@ -6,11 +6,15 @@ jobs:
6
6
  strategy:
7
7
  matrix:
8
8
  python-version: ['3.10', '3.11', '3.12', '3.13']
9
- numpy-version: ['1.26', 'dev']
9
+ numpy-version: ['1.26', '2.3', 'dev']
10
10
  exclude:
11
+ - python-version: '3.10'
12
+ numpy-version: '2.3'
13
+ - python-version: '3.10'
14
+ numpy-version: 'dev'
11
15
  - python-version: '3.13'
12
16
  numpy-version: '1.26'
13
- fail-fast: true
17
+ fail-fast: false
14
18
  steps:
15
19
  - uses: actions/checkout@v4
16
20
  - uses: actions/setup-python@v5
@@ -1,6 +1,32 @@
1
1
  # Changelog
2
2
 
3
- ## 2.4.0 (XXX)
3
+ ## 2.4.1 (2025-07-27)
4
+
5
+ ### Major Changes
6
+
7
+ - The array object defines `__array__` again when `__buffer__` is not available.
8
+
9
+ - Support for Python versions 3.10 and 3.11 has been reinstated.
10
+
11
+
12
+ ### Minor Changes
13
+
14
+ - Arithmetic operations no longer accept NumPy arrays.
15
+
16
+ - Disallow `__setitem__` for invalid dtype combinations (e.g. setting a float value
17
+ into an integer array)
18
+
19
+
20
+ ### Contributors
21
+
22
+ The following users contributed to this release:
23
+
24
+ Evgeni Burovski,
25
+ Lucas Colley,
26
+ Guido Imperiale
27
+
28
+
29
+ ## 2.4.0 (2025-06-16)
4
30
 
5
31
  ### Major Changes
6
32
 
@@ -39,7 +65,7 @@ The following users contributed to this release:
39
65
 
40
66
  Lumir Balhar,
41
67
  Evgeni Burovski,
42
- Joren Hammudoglu
68
+ Joren Hammudoglu,
43
69
  Tim Head,
44
70
  Guido Imperiale,
45
71
  Lucy Liu
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: array_api_strict
3
- Version: 2.4
3
+ Version: 2.4.1
4
4
  Summary: A strict, minimal implementation of the Python array API standard.
5
5
  Author: Consortium for Python Data API Standards
6
6
  License: Copyright (c) 2021-2024, NumPy Developers, Consortium for Python Data API Standards
@@ -16,6 +16,7 @@ of ndarray.
16
16
  from __future__ import annotations
17
17
 
18
18
  import operator
19
+ import sys
19
20
  from collections.abc import Iterator
20
21
  from enum import IntEnum
21
22
  from types import EllipsisType, ModuleType
@@ -67,8 +68,6 @@ class Device:
67
68
  CPU_DEVICE = Device()
68
69
  ALL_DEVICES = (CPU_DEVICE, Device("device1"), Device("device2"))
69
70
 
70
- _default = object()
71
-
72
71
 
73
72
  class Array:
74
73
  """
@@ -149,29 +148,40 @@ class Array:
149
148
 
150
149
  __str__ = __repr__
151
150
 
152
- # `__array__` was implemented historically for compatibility, and removing it has
153
- # caused issues for some libraries (see
154
- # https://github.com/data-apis/array-api-strict/issues/67).
155
-
156
- # Instead of `__array__` we now implement the buffer protocol.
157
- # Note that it makes array-apis-strict requiring python>=3.12
158
151
  def __buffer__(self, flags):
159
152
  if self._device != CPU_DEVICE:
160
- raise RuntimeError(f"Can not convert array on the '{self._device}' device to a Numpy array.")
153
+ raise RuntimeError(
154
+ # NumPy swallows this exception and falls back to __array__.
155
+ f"Can't extract host buffer from array on the '{self._device}' device."
156
+ )
161
157
  return self._array.__buffer__(flags)
162
158
 
163
- # We do not define __release_buffer__, per the discussion at
164
- # https://github.com/data-apis/array-api-strict/pull/115#pullrequestreview-2917178729
165
-
166
- def __array__(self, *args, **kwds):
167
- # a stub for python < 3.12; otherwise numpy silently produces object arrays
168
- import sys
169
- minor, major = sys.version_info.minor, sys.version_info.major
170
- if major < 3 or minor < 12:
159
+ # `__array__` is not part of the Array API. Ideally we want to support
160
+ # `xp.asarray(Array)` exclusively through the __buffer__ protocol; however this is
161
+ # only possible on Python >=3.12. Additionally, when __buffer__ raises (e.g. because
162
+ # the array is not on the CPU device, NumPy will try to fall back on __array__ but,
163
+ # if that doesn't exist, create a scalar numpy array of objects which contains the
164
+ # array_api_strict.Array. So we can't get rid of __array__ entirely.
165
+ def __array__(
166
+ self, dtype: None | np.dtype[Any] = None, copy: None | bool = None
167
+ ) -> npt.NDArray[Any]:
168
+ if self._device != CPU_DEVICE:
169
+ # We arrive here from np.asarray() on Python >=3.12 when __buffer__ raises.
170
+ raise RuntimeError(
171
+ f"Can't convert array on the '{self._device}' device to a "
172
+ "NumPy array."
173
+ )
174
+ if sys.version_info >= (3, 12):
171
175
  raise TypeError(
172
- "Interoperation with NumPy requires python >= 3.12. Please upgrade."
176
+ "The __array__ method is not supported by the Array API. "
177
+ "Please use the __buffer__ interface instead."
173
178
  )
174
179
 
180
+ # copy keyword is new in 2.0
181
+ if np.__version__[0] < '2':
182
+ return np.asarray(self._array, dtype=dtype)
183
+ return np.asarray(self._array, dtype=dtype, copy=copy)
184
+
175
185
  # These are various helper functions to make the array behavior match the
176
186
  # spec in places where it either deviates from or is more strict than
177
187
  # NumPy behavior
@@ -942,6 +952,15 @@ class Array:
942
952
  self._validate_index(key, op="setitem")
943
953
  # Indexing self._array with array_api_strict arrays can be erroneous
944
954
  np_key = key._array if isinstance(key, Array) else key
955
+
956
+ # sanitize the value
957
+ other = value
958
+ if isinstance(value, (bool, int, float, complex)):
959
+ other = self._promote_scalar(value)
960
+ dt = _result_type(self.dtype, other.dtype)
961
+ if dt != self.dtype:
962
+ raise TypeError(f"mismatched dtypes: {self.dtype = } and {other.dtype = }")
963
+
945
964
  self._array.__setitem__(np_key, asarray(value)._array)
946
965
 
947
966
  def __sub__(self, other: Array | complex, /) -> Array:
@@ -1104,6 +1123,7 @@ class Array:
1104
1123
  """
1105
1124
  Performs the operation __imod__.
1106
1125
  """
1126
+ self._check_type_device(other)
1107
1127
  other = self._check_allowed_dtypes(other, "real numeric", "__imod__")
1108
1128
  if other is NotImplemented:
1109
1129
  return other
@@ -1126,6 +1146,7 @@ class Array:
1126
1146
  """
1127
1147
  Performs the operation __imul__.
1128
1148
  """
1149
+ self._check_type_device(other)
1129
1150
  other = self._check_allowed_dtypes(other, "numeric", "__imul__")
1130
1151
  if other is NotImplemented:
1131
1152
  return other
@@ -1148,6 +1169,7 @@ class Array:
1148
1169
  """
1149
1170
  Performs the operation __ior__.
1150
1171
  """
1172
+ self._check_type_device(other)
1151
1173
  other = self._check_allowed_dtypes(other, "integer or boolean", "__ior__")
1152
1174
  if other is NotImplemented:
1153
1175
  return other
@@ -1170,6 +1192,7 @@ class Array:
1170
1192
  """
1171
1193
  Performs the operation __ipow__.
1172
1194
  """
1195
+ self._check_type_device(other)
1173
1196
  other = self._check_allowed_dtypes(other, "numeric", "__ipow__")
1174
1197
  if other is NotImplemented:
1175
1198
  return other
@@ -1182,6 +1205,7 @@ class Array:
1182
1205
  """
1183
1206
  from ._elementwise_functions import pow # type: ignore[attr-defined]
1184
1207
 
1208
+ self._check_type_device(other)
1185
1209
  other = self._check_allowed_dtypes(other, "numeric", "__rpow__")
1186
1210
  if other is NotImplemented:
1187
1211
  return other
@@ -1193,6 +1217,7 @@ class Array:
1193
1217
  """
1194
1218
  Performs the operation __irshift__.
1195
1219
  """
1220
+ self._check_type_device(other)
1196
1221
  other = self._check_allowed_dtypes(other, "integer", "__irshift__")
1197
1222
  if other is NotImplemented:
1198
1223
  return other
@@ -1215,6 +1240,7 @@ class Array:
1215
1240
  """
1216
1241
  Performs the operation __isub__.
1217
1242
  """
1243
+ self._check_type_device(other)
1218
1244
  other = self._check_allowed_dtypes(other, "numeric", "__isub__")
1219
1245
  if other is NotImplemented:
1220
1246
  return other
@@ -1237,6 +1263,7 @@ class Array:
1237
1263
  """
1238
1264
  Performs the operation __itruediv__.
1239
1265
  """
1266
+ self._check_type_device(other)
1240
1267
  other = self._check_allowed_dtypes(other, "floating-point", "__itruediv__")
1241
1268
  if other is NotImplemented:
1242
1269
  return other
@@ -1259,6 +1286,7 @@ class Array:
1259
1286
  """
1260
1287
  Performs the operation __ixor__.
1261
1288
  """
1289
+ self._check_type_device(other)
1262
1290
  other = self._check_allowed_dtypes(other, "integer or boolean", "__ixor__")
1263
1291
  if other is NotImplemented:
1264
1292
  return other
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.4'
21
- __version_tuple__ = version_tuple = (2, 4)
20
+ __version__ = version = '2.4.1'
21
+ __version_tuple__ = version_tuple = (2, 4, 1)
@@ -18,12 +18,14 @@ from .._dtypes import (
18
18
  _integer_or_boolean_dtypes,
19
19
  _real_numeric_dtypes,
20
20
  _numeric_dtypes,
21
+ uint8,
21
22
  int8,
22
23
  int16,
23
24
  int32,
24
25
  int64,
25
26
  uint64,
26
27
  float64,
28
+ complex128,
27
29
  bool as bool_,
28
30
  )
29
31
  from .._flags import set_array_api_strict_flags
@@ -193,6 +195,29 @@ def test_indexing_arrays_different_devices():
193
195
  a[idx1, idx2]
194
196
 
195
197
 
198
+ def test_setitem_invalid_promotions():
199
+ # Check that violating these two raises:
200
+ # Setting array values must not affect the data type of self, and
201
+ # Behavior must otherwise follow Type Promotion Rules.
202
+ a = asarray([1, 2, 3])
203
+ with pytest.raises(TypeError):
204
+ a[0] = 3.5
205
+
206
+ with pytest.raises(TypeError):
207
+ a[0] = asarray(3.5)
208
+
209
+ a = asarray([1, 2, 3], dtype=uint8)
210
+ with pytest.raises(TypeError):
211
+ a[0] = asarray(42, dtype=uint64)
212
+
213
+ a = asarray([1, 2, 3], dtype=float64)
214
+ with pytest.raises(TypeError):
215
+ a[0] = 3.5j
216
+
217
+ with pytest.raises(TypeError):
218
+ a[0] = asarray(3.5j, dtype=complex128)
219
+
220
+
196
221
  def test_promoted_scalar_inherits_device():
197
222
  device1 = Device("device1")
198
223
  x = asarray([1., 2, 3], device=device1)
@@ -344,6 +369,13 @@ def test_operators():
344
369
  getattr(x, _op)(y)
345
370
  else:
346
371
  assert_raises(TypeError, lambda: getattr(x, _op)(y))
372
+ # finally, test that array op ndarray raises
373
+ # XXX: as long as there is __array__ or __buffer__, __rop__s
374
+ # still return ndarrays
375
+ if not _op.startswith("__r"):
376
+ with assert_raises(TypeError):
377
+ getattr(x, _op)(y._array)
378
+
347
379
 
348
380
  for op, dtypes in unary_op_dtypes.items():
349
381
  for a in _array_vals():
@@ -527,36 +559,54 @@ def test_array_properties():
527
559
  assert b.mT.shape == (3, 2)
528
560
 
529
561
 
530
- @pytest.mark.xfail(sys.version_info.major*100 + sys.version_info.minor < 312,
531
- reason="array conversion relies on buffer protocol, and "
532
- "requires python >= 3.12"
533
- )
534
562
  def test_array_conversion():
535
563
  # Check that arrays on the CPU device can be converted to NumPy
536
564
  # but arrays on other devices can't. Note this is testing the logic in
537
- # __array__, which is only used in asarray when converting lists of
538
- # arrays.
565
+ # __array__ on Python 3.10~3.11 and in __buffer__ on Python >=3.12.
539
566
  a = ones((2, 3))
540
- np.asarray(a)
567
+ na = np.asarray(a)
568
+ assert na.shape == (2, 3)
569
+ assert na.dtype == np.float64
570
+ na[0, 0] = 10
571
+ assert a[0, 0] == 10 # return view when possible
572
+
573
+ a = arange(5, dtype=uint8)
574
+ na = np.asarray(a)
575
+ assert na.dtype == np.uint8
541
576
 
542
577
  for device in ("device1", "device2"):
543
578
  a = ones((2, 3), device=array_api_strict.Device(device))
544
- with pytest.raises((RuntimeError, ValueError)):
579
+ with pytest.raises(RuntimeError, match=device):
545
580
  np.asarray(a)
546
581
 
547
- # __buffer__ should work for now for conversion to numpy
548
- a = ones((2, 3))
549
- na = np.array(a)
550
- assert na.shape == (2, 3)
551
- assert na.dtype == np.float64
552
582
 
553
- @pytest.mark.skipif(not sys.version_info.major*100 + sys.version_info.minor < 312,
554
- reason="conversion to numpy errors out unless python >= 3.12"
583
+ @pytest.mark.skipif(np.__version__ < "2", reason="np.asarray has no copy kwarg")
584
+ def test_array_conversion_copy():
585
+ a = arange(5)
586
+ na = np.asarray(a, copy=False)
587
+ na[0] = 10
588
+ assert a[0] == 10
589
+
590
+ a = arange(5)
591
+ na = np.asarray(a, copy=True)
592
+ na[0] = 10
593
+ assert a[0] == 0
594
+
595
+ a = arange(5)
596
+ with pytest.raises(ValueError):
597
+ np.asarray(a, dtype=np.uint8, copy=False)
598
+
599
+
600
+ @pytest.mark.skipif(
601
+ sys.version_info < (3, 12), reason="Python <3.12 has no __buffer__ interface"
555
602
  )
556
- def test_array_conversion_2():
603
+ def test_no_array_interface():
604
+ """When the __buffer__ interface is available, the __array__ interface is not."""
557
605
  a = ones((2, 3))
558
- with pytest.raises(TypeError):
559
- np.array(a)
606
+ with pytest.raises(TypeError, match="not supported"):
607
+ # Because NumPy prefers __buffer__ when available, we can't trigger this
608
+ # exception from np.asarray().
609
+ a.__array__()
560
610
 
561
611
 
562
612
  def test_allow_newaxis():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: array_api_strict
3
- Version: 2.4
3
+ Version: 2.4.1
4
4
  Summary: A strict, minimal implementation of the Python array API standard.
5
5
  Author: Consortium for Python Data API Standards
6
6
  License: Copyright (c) 2021-2024, NumPy Developers, Consortium for Python Data API Standards
@@ -1,6 +1,32 @@
1
1
  # Changelog
2
2
 
3
- ## 2.4.0 (XXX)
3
+ ## 2.4.1 (2025-07-27)
4
+
5
+ ### Major Changes
6
+
7
+ - The array object defines `__array__` again when `__buffer__` is not available.
8
+
9
+ - Support for Python versions 3.10 and 3.11 has been reinstated.
10
+
11
+
12
+ ### Minor Changes
13
+
14
+ - Arithmetic operations no longer accept NumPy arrays.
15
+
16
+ - Disallow `__setitem__` for invalid dtype combinations (e.g. setting a float value
17
+ into an integer array)
18
+
19
+
20
+ ### Contributors
21
+
22
+ The following users contributed to this release:
23
+
24
+ Evgeni Burovski,
25
+ Lucas Colley,
26
+ Guido Imperiale
27
+
28
+
29
+ ## 2.4.0 (2025-06-16)
4
30
 
5
31
  ### Major Changes
6
32
 
@@ -39,7 +65,7 @@ The following users contributed to this release:
39
65
 
40
66
  Lumir Balhar,
41
67
  Evgeni Burovski,
42
- Joren Hammudoglu
68
+ Joren Hammudoglu,
43
69
  Tim Head,
44
70
  Guido Imperiale,
45
71
  Lucy Liu
File without changes