array-api-strict 2.1.2__tar.gz → 2.1.3__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 (48) hide show
  1. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/PKG-INFO +4 -5
  2. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/__init__.py +0 -6
  3. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_array_object.py +44 -17
  4. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_creation_functions.py +23 -0
  5. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_version.py +3 -3
  6. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_array_object.py +55 -16
  7. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict.egg-info/PKG-INFO +4 -5
  8. array_api_strict-2.1.3/array_api_strict.egg-info/requires.txt +1 -0
  9. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/setup.py +3 -4
  10. array_api_strict-2.1.2/array_api_strict.egg-info/requires.txt +0 -1
  11. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/LICENSE +0 -0
  12. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/README.md +0 -0
  13. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_constants.py +0 -0
  14. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_data_type_functions.py +0 -0
  15. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_dtypes.py +0 -0
  16. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_elementwise_functions.py +0 -0
  17. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_fft.py +0 -0
  18. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_flags.py +0 -0
  19. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_indexing_functions.py +0 -0
  20. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_info.py +0 -0
  21. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_linalg.py +0 -0
  22. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_linear_algebra_functions.py +0 -0
  23. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_manipulation_functions.py +0 -0
  24. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_searching_functions.py +0 -0
  25. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_set_functions.py +0 -0
  26. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_sorting_functions.py +0 -0
  27. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_statistical_functions.py +0 -0
  28. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_typing.py +0 -0
  29. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/_utility_functions.py +0 -0
  30. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/__init__.py +0 -0
  31. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/conftest.py +0 -0
  32. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_creation_functions.py +0 -0
  33. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_data_type_functions.py +0 -0
  34. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_device_support.py +0 -0
  35. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_elementwise_functions.py +0 -0
  36. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_flags.py +0 -0
  37. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_indexing_functions.py +0 -0
  38. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_linalg.py +0 -0
  39. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_manipulation_functions.py +0 -0
  40. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_set_functions.py +0 -0
  41. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_sorting_functions.py +0 -0
  42. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_statistical_functions.py +0 -0
  43. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict/tests/test_validation.py +0 -0
  44. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict.egg-info/SOURCES.txt +0 -0
  45. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict.egg-info/dependency_links.txt +0 -0
  46. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/array_api_strict.egg-info/top_level.txt +0 -0
  47. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/setup.cfg +0 -0
  48. {array_api_strict-2.1.2 → array_api_strict-2.1.3}/versioneer.py +0 -0
@@ -1,22 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: array_api_strict
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: A strict, minimal implementation of the Python array API standard.
5
5
  Home-page: https://data-apis.org/array-api-strict/
6
6
  Author: Consortium for Python Data API Standards
7
7
  License: MIT
8
8
  Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
9
10
  Classifier: Programming Language :: Python :: 3.10
10
11
  Classifier: Programming Language :: Python :: 3.11
11
12
  Classifier: Programming Language :: Python :: 3.12
12
- Classifier: Programming Language :: Python :: 3.13
13
- Classifier: Intended Audience :: Developers
14
13
  Classifier: License :: OSI Approved :: BSD License
15
14
  Classifier: Operating System :: OS Independent
16
- Requires-Python: >=3.10
15
+ Requires-Python: >=3.9
17
16
  Description-Content-Type: text/markdown
18
17
  License-File: LICENSE
19
- Requires-Dist: numpy>=2.1
18
+ Requires-Dist: numpy
20
19
 
21
20
  # array-api-strict
22
21
 
@@ -16,12 +16,6 @@ consuming libraries to test their array API usage.
16
16
 
17
17
  """
18
18
 
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
-
25
19
  __all__ = []
26
20
 
27
21
  # Warning: __array_api_version__ could change globally with
@@ -66,7 +66,9 @@ ALL_DEVICES = (CPU_DEVICE, Device("device1"), Device("device2"))
66
66
 
67
67
  _default = object()
68
68
 
69
- _allow_array = False
69
+ # See https://github.com/data-apis/array-api-strict/issues/67 and the comment
70
+ # on __array__ below.
71
+ _allow_array = True
70
72
 
71
73
  class Array:
72
74
  """
@@ -147,22 +149,37 @@ class Array:
147
149
  mid = np.array2string(self._array, separator=', ', prefix=prefix, suffix=suffix)
148
150
  return prefix + mid + suffix
149
151
 
150
- # Disallow __array__, meaning calling `np.func()` on an array_api_strict
151
- # array will give an error. If we don't explicitly disallow it, NumPy
152
- # defaults to creating an object dtype array, which would lead to
153
- # confusing error messages at best and surprising bugs at worst.
154
- #
155
- # The alternative of course is to just support __array__, which is what we
156
- # used to do. But this isn't actually supported by the standard, so it can
152
+ # In the future, _allow_array will be set to False, which will disallow
153
+ # __array__. This means calling `np.func()` on an array_api_strict array
154
+ # will give an error. If we don't explicitly disallow it, NumPy defaults
155
+ # to creating an object dtype array, which would lead to confusing error
156
+ # messages at best and surprising bugs at worst. The reason for doing this
157
+ # is that __array__ is not actually supported by the standard, so it can
157
158
  # lead to code assuming np.asarray(other_array) would always work in the
158
159
  # standard.
160
+ #
161
+ # This was implemented historically for compatibility, and removing it has
162
+ # caused issues for some libraries (see
163
+ # https://github.com/data-apis/array-api-strict/issues/67).
159
164
  def __array__(self, dtype: None | np.dtype[Any] = None, copy: None | bool = None) -> npt.NDArray[Any]:
160
165
  # We have to allow this to be internally enabled as there's no other
161
166
  # easy way to parse a list of Array objects in asarray().
162
167
  if _allow_array:
163
168
  if self._device != CPU_DEVICE:
164
169
  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)
170
+ # copy keyword is new in 2.0.0; for older versions don't use it
171
+ # retry without that keyword.
172
+ if np.__version__[0] < '2':
173
+ return np.asarray(self._array, dtype=dtype)
174
+ elif np.__version__.startswith('2.0.0-dev0'):
175
+ # Handle dev version for which we can't know based on version
176
+ # number whether or not the copy keyword is supported.
177
+ try:
178
+ return np.asarray(self._array, dtype=dtype, copy=copy)
179
+ except TypeError:
180
+ return np.asarray(self._array, dtype=dtype)
181
+ else:
182
+ return np.asarray(self._array, dtype=dtype, copy=copy)
166
183
  raise ValueError("Conversion from an array_api_strict array to a NumPy ndarray is not supported")
167
184
 
168
185
  # These are various helper functions to make the array behavior match the
@@ -574,14 +591,24 @@ class Array:
574
591
  if copy is not _default:
575
592
  raise ValueError("The copy argument to __dlpack__ requires at least version 2023.12 of the array API")
576
593
 
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)
594
+ if np.lib.NumpyVersion(np.__version__) < '2.1.0':
595
+ if max_version not in [_default, None]:
596
+ raise NotImplementedError("The max_version argument to __dlpack__ is not yet implemented")
597
+ if dl_device not in [_default, None]:
598
+ raise NotImplementedError("The device argument to __dlpack__ is not yet implemented")
599
+ if copy not in [_default, None]:
600
+ raise NotImplementedError("The copy argument to __dlpack__ is not yet implemented")
601
+
602
+ return self._array.__dlpack__(stream=stream)
603
+ else:
604
+ kwargs = {'stream': stream}
605
+ if max_version is not _default:
606
+ kwargs['max_version'] = max_version
607
+ if dl_device is not _default:
608
+ kwargs['dl_device'] = dl_device
609
+ if copy is not _default:
610
+ kwargs['copy'] = copy
611
+ return self._array.__dlpack__(**kwargs)
585
612
 
586
613
  def __dlpack_device__(self: Array, /) -> Tuple[IntEnum, int]:
587
614
  """
@@ -83,6 +83,29 @@ def asarray(
83
83
  if isinstance(obj, Array) and device is None:
84
84
  device = obj.device
85
85
 
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
+
86
109
  if isinstance(obj, Array):
87
110
  return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype), device=device)
88
111
  if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)):
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-11-07T18:09:02-0700",
11
+ "date": "2024-11-08T16:00:41-0700",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "c9fe697bec8de8e402d8beb71bbeb96ca70c772e",
15
- "version": "2.1.2"
14
+ "full-revisionid": "310bb626b04ea61e24feca146440dd4ec1f6cf5b",
15
+ "version": "2.1.3"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -364,6 +364,23 @@ def test_array_conversion():
364
364
  with pytest.raises(RuntimeError, match="Can not convert array"):
365
365
  asarray([a])
366
366
 
367
+ def test__array__():
368
+ # __array__ should work for now
369
+ a = ones((2, 3))
370
+ np.array(a)
371
+
372
+ # Test the _allow_array private global flag for disabling it in the
373
+ # future.
374
+ from .. import _array_object
375
+ original_value = _array_object._allow_array
376
+ try:
377
+ _array_object._allow_array = False
378
+ a = ones((2, 3))
379
+ with pytest.raises(ValueError, match="Conversion from an array_api_strict array to a NumPy ndarray is not supported"):
380
+ np.array(a)
381
+ finally:
382
+ _array_object._allow_array = original_value
383
+
367
384
  def test_allow_newaxis():
368
385
  a = ones(5)
369
386
  indexed_a = a[None, :]
@@ -448,7 +465,7 @@ def test_iter():
448
465
  pytest.raises(TypeError, lambda: iter(ones((3, 3))))
449
466
 
450
467
  @pytest.mark.parametrize("api_version", ['2021.12', '2022.12', '2023.12'])
451
- def dlpack_2023_12(api_version):
468
+ def test_dlpack_2023_12(api_version):
452
469
  if api_version == '2021.12':
453
470
  with pytest.warns(UserWarning):
454
471
  set_array_api_strict_flags(api_version=api_version)
@@ -456,19 +473,41 @@ def dlpack_2023_12(api_version):
456
473
  set_array_api_strict_flags(api_version=api_version)
457
474
 
458
475
  a = asarray([1, 2, 3], dtype=int8)
459
-
460
- # Do not error
476
+ # Never an error
461
477
  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]))
478
+
479
+ if api_version < '2023.12':
480
+ pytest.raises(ValueError, lambda:
481
+ a.__dlpack__(dl_device=a.__dlpack_device__()))
482
+ pytest.raises(ValueError, lambda:
483
+ a.__dlpack__(dl_device=None))
484
+ pytest.raises(ValueError, lambda:
485
+ a.__dlpack__(max_version=(1, 0)))
486
+ pytest.raises(ValueError, lambda:
487
+ a.__dlpack__(max_version=None))
488
+ pytest.raises(ValueError, lambda:
489
+ a.__dlpack__(copy=False))
490
+ pytest.raises(ValueError, lambda:
491
+ a.__dlpack__(copy=True))
492
+ pytest.raises(ValueError, lambda:
493
+ a.__dlpack__(copy=None))
494
+ elif np.lib.NumpyVersion(np.__version__) < '2.1.0':
495
+ pytest.raises(NotImplementedError, lambda:
496
+ a.__dlpack__(dl_device=CPU_DEVICE))
497
+ a.__dlpack__(dl_device=None)
498
+ pytest.raises(NotImplementedError, lambda:
499
+ a.__dlpack__(max_version=(1, 0)))
500
+ a.__dlpack__(max_version=None)
501
+ pytest.raises(NotImplementedError, lambda:
502
+ a.__dlpack__(copy=False))
503
+ pytest.raises(NotImplementedError, lambda:
504
+ a.__dlpack__(copy=True))
505
+ a.__dlpack__(copy=None)
506
+ else:
507
+ a.__dlpack__(dl_device=a.__dlpack_device__())
508
+ a.__dlpack__(dl_device=None)
509
+ a.__dlpack__(max_version=(1, 0))
510
+ a.__dlpack__(max_version=None)
511
+ a.__dlpack__(copy=False)
512
+ a.__dlpack__(copy=True)
513
+ a.__dlpack__(copy=None)
@@ -1,22 +1,21 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: array_api_strict
3
- Version: 2.1.2
3
+ Version: 2.1.3
4
4
  Summary: A strict, minimal implementation of the Python array API standard.
5
5
  Home-page: https://data-apis.org/array-api-strict/
6
6
  Author: Consortium for Python Data API Standards
7
7
  License: MIT
8
8
  Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
9
10
  Classifier: Programming Language :: Python :: 3.10
10
11
  Classifier: Programming Language :: Python :: 3.11
11
12
  Classifier: Programming Language :: Python :: 3.12
12
- Classifier: Programming Language :: Python :: 3.13
13
- Classifier: Intended Audience :: Developers
14
13
  Classifier: License :: OSI Approved :: BSD License
15
14
  Classifier: Operating System :: OS Independent
16
- Requires-Python: >=3.10
15
+ Requires-Python: >=3.9
17
16
  Description-Content-Type: text/markdown
18
17
  License-File: LICENSE
19
- Requires-Dist: numpy>=2.1
18
+ Requires-Dist: numpy
20
19
 
21
20
  # array-api-strict
22
21
 
@@ -15,15 +15,14 @@ setup(
15
15
  long_description_content_type="text/markdown",
16
16
  url="https://data-apis.org/array-api-strict/",
17
17
  license="MIT",
18
- python_requires=">=3.10",
19
- install_requires=["numpy>=2.1"],
18
+ python_requires=">=3.9",
19
+ install_requires=["numpy"],
20
20
  classifiers=[
21
21
  "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
22
23
  "Programming Language :: Python :: 3.10",
23
24
  "Programming Language :: Python :: 3.11",
24
25
  "Programming Language :: Python :: 3.12",
25
- "Programming Language :: Python :: 3.13",
26
- "Intended Audience :: Developers",
27
26
  "License :: OSI Approved :: BSD License",
28
27
  "Operating System :: OS Independent",
29
28
  ],
@@ -1 +0,0 @@
1
- numpy>=2.1