array-api-strict 1.0__py3-none-any.whl → 1.1.1__py3-none-any.whl

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.
@@ -17,6 +17,8 @@ from __future__ import annotations
17
17
 
18
18
  import operator
19
19
  from enum import IntEnum
20
+ import warnings
21
+
20
22
  from ._creation_functions import asarray
21
23
  from ._dtypes import (
22
24
  _DType,
@@ -122,14 +124,26 @@ class Array:
122
124
 
123
125
  # This function is not required by the spec, but we implement it here for
124
126
  # convenience so that np.asarray(array_api_strict.Array) will work.
125
- def __array__(self, dtype: None | np.dtype[Any] = None) -> npt.NDArray[Any]:
127
+ def __array__(self, dtype: None | np.dtype[Any] = None, copy: None | bool = None) -> npt.NDArray[Any]:
126
128
  """
127
129
  Warning: this method is NOT part of the array API spec. Implementers
128
130
  of other libraries need not include it, and users should not assume it
129
131
  will be present in other implementations.
130
132
 
131
133
  """
132
- return np.asarray(self._array, dtype=dtype)
134
+ # copy keyword is new in 2.0.0; for older versions don't use it
135
+ # retry without that keyword.
136
+ if np.__version__[0] < '2':
137
+ return np.asarray(self._array, dtype=dtype)
138
+ elif np.__version__.startswith('2.0.0-dev0'):
139
+ # Handle dev version for which we can't know based on version
140
+ # number whether or not the copy keyword is supported.
141
+ try:
142
+ return np.asarray(self._array, dtype=dtype, copy=copy)
143
+ except TypeError:
144
+ return np.asarray(self._array, dtype=dtype)
145
+ else:
146
+ return np.asarray(self._array, dtype=dtype, copy=copy)
133
147
 
134
148
  # These are various helper functions to make the array behavior match the
135
149
  # spec in places where it either deviates from or is more strict than
@@ -468,8 +482,10 @@ class Array:
468
482
  def __array_namespace__(
469
483
  self: Array, /, *, api_version: Optional[str] = None
470
484
  ) -> types.ModuleType:
471
- if api_version is not None and not api_version.startswith("2021."):
485
+ if api_version is not None and api_version not in ["2021.12", "2022.12"]:
472
486
  raise ValueError(f"Unrecognized array API version: {api_version!r}")
487
+ if api_version == "2021.12":
488
+ warnings.warn("The 2021.12 version of the array API specification was requested but the returned namespace is actually version 2022.12")
473
489
  import array_api_strict
474
490
  return array_api_strict
475
491
 
@@ -11,7 +11,6 @@ if TYPE_CHECKING:
11
11
  NestedSequence,
12
12
  SupportsBufferProtocol,
13
13
  )
14
- from collections.abc import Sequence
15
14
  from ._dtypes import _DType, _all_dtypes
16
15
 
17
16
  import numpy as np
@@ -22,6 +21,12 @@ def _check_valid_dtype(dtype):
22
21
  if dtype not in (None,) + _all_dtypes:
23
22
  raise ValueError("dtype must be one of the supported dtypes")
24
23
 
24
+ def _supports_buffer_protocol(obj):
25
+ try:
26
+ memoryview(obj)
27
+ except TypeError:
28
+ return False
29
+ return True
25
30
 
26
31
  def asarray(
27
32
  obj: Union[
@@ -36,7 +41,7 @@ def asarray(
36
41
  *,
37
42
  dtype: Optional[Dtype] = None,
38
43
  device: Optional[Device] = None,
39
- copy: Optional[Union[bool, np._CopyMode]] = None,
44
+ copy: Optional[bool] = None,
40
45
  ) -> Array:
41
46
  """
42
47
  Array API compatible wrapper for :py:func:`np.asarray <numpy.asarray>`.
@@ -53,20 +58,37 @@ def asarray(
53
58
  _np_dtype = dtype._np_dtype
54
59
  if device not in [CPU_DEVICE, None]:
55
60
  raise ValueError(f"Unsupported device {device!r}")
56
- if copy in (False, np._CopyMode.IF_NEEDED):
57
- # Note: copy=False is not yet implemented in np.asarray
58
- raise NotImplementedError("copy=False is not yet implemented")
61
+
62
+ if np.__version__[0] < '2':
63
+ if copy is False:
64
+ # Note: copy=False is not yet implemented in np.asarray for
65
+ # NumPy 1
66
+
67
+ # Work around it by creating the new array and seeing if NumPy
68
+ # copies it.
69
+ if isinstance(obj, Array):
70
+ new_array = np.array(obj._array, copy=copy, dtype=_np_dtype)
71
+ if new_array is not obj._array:
72
+ raise ValueError("Unable to avoid copy while creating an array from given array.")
73
+ return Array._new(new_array)
74
+ elif _supports_buffer_protocol(obj):
75
+ # Buffer protocol will always support no-copy
76
+ return Array._new(np.array(obj, copy=copy, dtype=_np_dtype))
77
+ else:
78
+ # No-copy is unsupported for Python built-in types.
79
+ raise ValueError("Unable to avoid copy while creating an array from given object.")
80
+
81
+ if copy is None:
82
+ # NumPy 1 treats copy=False the same as the standard copy=None
83
+ copy = False
84
+
59
85
  if isinstance(obj, Array):
60
- if dtype is not None and obj.dtype != dtype:
61
- copy = True
62
- if copy in (True, np._CopyMode.ALWAYS):
63
- return Array._new(np.array(obj._array, copy=True, dtype=_np_dtype))
64
- return obj
86
+ return Array._new(np.array(obj._array, copy=copy, dtype=_np_dtype))
65
87
  if dtype is None and isinstance(obj, int) and (obj > 2 ** 64 or obj < -(2 ** 63)):
66
88
  # Give a better error message in this case. NumPy would convert this
67
89
  # to an object array. TODO: This won't handle large integers in lists.
68
90
  raise OverflowError("Integer out of bounds for array dtypes")
69
- res = np.asarray(obj, dtype=_np_dtype)
91
+ res = np.array(obj, dtype=_np_dtype, copy=copy)
70
92
  return Array._new(res)
71
93
 
72
94
 
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-01-24T13:16:13-0700",
11
+ "date": "2024-03-29T16:44:48-0600",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "c0f153460b1881115ceccfad854dc5d9ae346f55",
15
- "version": "1.0"
14
+ "full-revisionid": "b835dd24b8702b23e0b40dae82783dabeeb5d8e1",
15
+ "version": "1.1.1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -73,9 +73,6 @@ def cross(x1: Array, x2: Array, /, *, axis: int = -1) -> Array:
73
73
  """
74
74
  if x1.dtype not in _numeric_dtypes or x2.dtype not in _numeric_dtypes:
75
75
  raise TypeError('Only numeric dtypes are allowed in cross')
76
- # Note: this is different from np.cross(), which broadcasts
77
- if x1.shape != x2.shape:
78
- raise ValueError('x1 and x2 must have the same shape')
79
76
  if x1.ndim == 0:
80
77
  raise ValueError('cross() requires arrays of dimension at least 1')
81
78
  # Note: this is different from np.cross(), which allows dimension 2
@@ -23,7 +23,7 @@ from .._dtypes import (
23
23
  uint64,
24
24
  bool as bool_,
25
25
  )
26
-
26
+ import array_api_strict
27
27
 
28
28
  def test_validate_index():
29
29
  # The indexing tests in the official array API test suite test that the
@@ -398,3 +398,13 @@ def test_array_keys_use_private_array():
398
398
  key = ones((0, 0), dtype=bool_)
399
399
  with pytest.raises(IndexError):
400
400
  a[key]
401
+
402
+ def test_array_namespace():
403
+ a = ones((3, 3))
404
+ assert a.__array_namespace__() == array_api_strict
405
+ assert a.__array_namespace__(api_version=None) is array_api_strict
406
+ assert a.__array_namespace__(api_version="2022.12") is array_api_strict
407
+ with pytest.warns(UserWarning):
408
+ assert a.__array_namespace__(api_version="2021.12") is array_api_strict
409
+ pytest.raises(ValueError, lambda: a.__array_namespace__(api_version="2021.11"))
410
+ pytest.raises(ValueError, lambda: a.__array_namespace__(api_version="2023.12"))
@@ -50,19 +50,49 @@ def test_asarray_copy():
50
50
  a[0] = 0
51
51
  assert all(b[0] == 1)
52
52
  assert all(a[0] == 0)
53
+
53
54
  a = asarray([1])
54
- b = asarray(a, copy=np._CopyMode.ALWAYS)
55
+ b = asarray(a, copy=False)
55
56
  a[0] = 0
56
- assert all(b[0] == 1)
57
- assert all(a[0] == 0)
57
+ assert all(b[0] == 0)
58
+
59
+ a = asarray([1])
60
+ assert_raises(ValueError, lambda: asarray(a, copy=False, dtype=float64))
61
+
62
+ a = asarray([1])
63
+ b = asarray(a, copy=None)
64
+ a[0] = 0
65
+ assert all(b[0] == 0)
66
+
58
67
  a = asarray([1])
59
- b = asarray(a, copy=np._CopyMode.NEVER)
68
+ b = asarray(a, dtype=float64, copy=None)
69
+ a[0] = 0
70
+ assert all(b[0] == 1.0)
71
+
72
+ # Python built-in types
73
+ for obj in [True, 0, 0.0, 0j, [0], [[0]]]:
74
+ asarray(obj, copy=True) # No error
75
+ asarray(obj, copy=None) # No error
76
+ assert_raises(ValueError, lambda: asarray(obj, copy=False))
77
+
78
+ # Buffer protocol
79
+ a = np.array([1])
80
+ b = asarray(a, copy=True)
81
+ assert isinstance(b, Array)
82
+ a[0] = 0
83
+ assert all(b[0] == 1)
84
+
85
+ a = np.array([1])
86
+ b = asarray(a, copy=False)
87
+ assert isinstance(b, Array)
60
88
  a[0] = 0
61
89
  assert all(b[0] == 0)
62
- assert_raises(NotImplementedError, lambda: asarray(a, copy=False))
63
- assert_raises(NotImplementedError,
64
- lambda: asarray(a, copy=np._CopyMode.IF_NEEDED))
65
90
 
91
+ a = np.array([1])
92
+ b = asarray(a, copy=None)
93
+ assert isinstance(b, Array)
94
+ a[0] = 0
95
+ assert all(b[0] == 0)
66
96
 
67
97
  def test_arange_errors():
68
98
  arange(1, device=CPU_DEVICE) # Doesn't error
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: array_api_strict
3
- Version: 1.0
3
+ Version: 1.1.1
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
@@ -34,6 +34,10 @@ libraries. Consuming library code should use the
34
34
  support the array API. Rather, it is intended to be used in the test suites of
35
35
  consuming libraries to test their array API usage.
36
36
 
37
+ array-api-strict currently supports the 2022.12 version of the standard.
38
+ 2023.12 support is planned and is tracked by [this
39
+ issue](https://github.com/data-apis/array-api-strict/issues/25).
40
+
37
41
  ## Install
38
42
 
39
43
  `array-api-strict` is available on both
@@ -1,7 +1,7 @@
1
1
  array_api_strict/__init__.py,sha256=cXEybrrXZOSyqr1JtCDKnKWCrMycZuVd_J6jdHgvnso,5061
2
- array_api_strict/_array_object.py,sha256=hi2rHZDTOw0UHNO95U5-eoE16vfiVY0vK-OeaQpzifY,44292
2
+ array_api_strict/_array_object.py,sha256=uusWUXgJQnbxrOEiNK2JiwiZaXXhLe-qm9iGWn6fH7I,45131
3
3
  array_api_strict/_constants.py,sha256=AYayN2jf1Dp5rXZ7WPBdUhtPBo_JMCi-pD9oW5zmFkI,87
4
- array_api_strict/_creation_functions.py,sha256=7C-5i7c_ADUoeP5oN1r-mVzNP3esWM2WSO98xN65g0Y,10829
4
+ array_api_strict/_creation_functions.py,sha256=rcgdgxmRWFg1FWW8IkBqlk8PuMatlpD5rz3LLErTgh4,11640
5
5
  array_api_strict/_data_type_functions.py,sha256=LJc62mWGtRsgfDS4M3WlCdl51HojcP7jApmcwdJ55l8,6436
6
6
  array_api_strict/_dtypes.py,sha256=aNZleHcEqemH2-mCijrFr8dxMQQJoMXNnvThbXZ4awc,6208
7
7
  array_api_strict/_elementwise_functions.py,sha256=0kGuDX3Ur_Qp6tBMBWTO7LPUxzXNGAlA2SSJhdAp4DU,25992
@@ -13,12 +13,12 @@ array_api_strict/_sorting_functions.py,sha256=7pszlxNN7-DNqEZlonGLFQrlXPP7evVA8j
13
13
  array_api_strict/_statistical_functions.py,sha256=I2k2Ql-Bdwh8VmvqfeQdZjncHiMQHGzolCbFIl65aoY,3680
14
14
  array_api_strict/_typing.py,sha256=VVqlHrb4qFCQ-wn5Xrs4BmNk_lnh5X4yBx5iafdMwho,1112
15
15
  array_api_strict/_utility_functions.py,sha256=HwycylbPAgRVz4nZvjvwqN3mQnJbqKA-NRMaAvIP-CE,824
16
- array_api_strict/_version.py,sha256=VsI7Etj8obFBBab7V6GzmRBA3BqWGKOFtbo9OYpCaLQ,495
16
+ array_api_strict/_version.py,sha256=fS-cEEmAWOk_mE_jDhBRGyz9bT0V4MGj9-B2_A2jZtM,497
17
17
  array_api_strict/fft.py,sha256=YuyPom-zog_i-yLSYFw300CFdPCJc7xbU0gq1UHXlNg,8996
18
- array_api_strict/linalg.py,sha256=MQqoSMayWhPdrQDFjWVzPX83Nat31j7SiDtpAguhGX4,18712
18
+ array_api_strict/linalg.py,sha256=PhspNehj7Ag8RF3piB-A_FRXUTm-6Fwrr8sUe8lG1l0,18556
19
19
  array_api_strict/tests/__init__.py,sha256=t_2GZ3lKcsu4ec4GMKPUDYaeMUJyDquBlQAcPgj7kFE,282
20
- array_api_strict/tests/test_array_object.py,sha256=N_Leal0TBEPnx8gzCXGtex-kTtnJ-Q_4_Yk1bC8kHeo,17300
21
- array_api_strict/tests/test_creation_functions.py,sha256=e1AvqOwJxccQoDfO9GvSQ7i8cr-4QADLpeQnO1zzqsQ,6109
20
+ array_api_strict/tests/test_array_object.py,sha256=LdTakMvT42AvtAjbn1i-FmhpaHuPchWoI6woUSB3ef4,17859
21
+ array_api_strict/tests/test_creation_functions.py,sha256=dO3b22XOy3quhUG8gFNvy_n_0OdDcTcvTSrrNLBrASU,6711
22
22
  array_api_strict/tests/test_data_type_functions.py,sha256=hZ1r3jIsZ9CE746b2doMwORPqgxXhx8dXj27CS07t7E,1292
23
23
  array_api_strict/tests/test_elementwise_functions.py,sha256=CTj4LLwtusI51HkpzD0JPohP1ffNxogAVFz8WLuWFzM,3800
24
24
  array_api_strict/tests/test_indexing_functions.py,sha256=srT5EUcIfmyq6Um8OXIzq-mQPzvlDseksttywBslGME,622
@@ -26,8 +26,8 @@ array_api_strict/tests/test_manipulation_functions.py,sha256=wce25dSJjubrGhFxmia
26
26
  array_api_strict/tests/test_set_functions.py,sha256=ikzab1j3SXxGf0OqwHrOAM13HwQetdhtB60Zc_gc1DE,542
27
27
  array_api_strict/tests/test_sorting_functions.py,sha256=fJ1ahz8ihYTb9SylqNXufMRdHMwGSzK2n6LFx29KzaU,598
28
28
  array_api_strict/tests/test_validation.py,sha256=JdsK4z1M0U5YoJrfWSzOpEhmlehvZHF5SG0I0k6oDy8,672
29
- array_api_strict-1.0.dist-info/LICENSE,sha256=djDm4UfHAJmycwFUNyUmrTdRkrFF9Ac8uqIlbxH7j5Y,1585
30
- array_api_strict-1.0.dist-info/METADATA,sha256=N9tT-KKo0X-JyMLiDeVH-sQN3g62UYNxi6xYf5rgt5U,9825
31
- array_api_strict-1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
32
- array_api_strict-1.0.dist-info/top_level.txt,sha256=M4cE8VLgRHp_d9TPkbk7_I4JriELFdEJz-NKJJqAkAE,17
33
- array_api_strict-1.0.dist-info/RECORD,,
29
+ array_api_strict-1.1.1.dist-info/LICENSE,sha256=djDm4UfHAJmycwFUNyUmrTdRkrFF9Ac8uqIlbxH7j5Y,1585
30
+ array_api_strict-1.1.1.dist-info/METADATA,sha256=sQr0eTZZdSxnqueYYD8YVhtpPg0wEsILpKWyEyWhf1Q,10017
31
+ array_api_strict-1.1.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
32
+ array_api_strict-1.1.1.dist-info/top_level.txt,sha256=M4cE8VLgRHp_d9TPkbk7_I4JriELFdEJz-NKJJqAkAE,17
33
+ array_api_strict-1.1.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: bdist_wheel (0.43.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5