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.
- array_api_strict/_array_object.py +19 -3
- array_api_strict/_creation_functions.py +33 -11
- array_api_strict/_version.py +3 -3
- array_api_strict/linalg.py +0 -3
- array_api_strict/tests/test_array_object.py +11 -1
- array_api_strict/tests/test_creation_functions.py +37 -7
- {array_api_strict-1.0.dist-info → array_api_strict-1.1.1.dist-info}/METADATA +5 -1
- {array_api_strict-1.0.dist-info → array_api_strict-1.1.1.dist-info}/RECORD +11 -11
- {array_api_strict-1.0.dist-info → array_api_strict-1.1.1.dist-info}/WHEEL +1 -1
- {array_api_strict-1.0.dist-info → array_api_strict-1.1.1.dist-info}/LICENSE +0 -0
- {array_api_strict-1.0.dist-info → array_api_strict-1.1.1.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
|
|
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
|
|
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[
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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.
|
|
91
|
+
res = np.array(obj, dtype=_np_dtype, copy=copy)
|
|
70
92
|
return Array._new(res)
|
|
71
93
|
|
|
72
94
|
|
array_api_strict/_version.py
CHANGED
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-
|
|
11
|
+
"date": "2024-03-29T16:44:48-0600",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.
|
|
14
|
+
"full-revisionid": "b835dd24b8702b23e0b40dae82783dabeeb5d8e1",
|
|
15
|
+
"version": "1.1.1"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
array_api_strict/linalg.py
CHANGED
|
@@ -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=
|
|
55
|
+
b = asarray(a, copy=False)
|
|
55
56
|
a[0] = 0
|
|
56
|
-
assert all(b[0] ==
|
|
57
|
-
|
|
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=
|
|
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
21
|
-
array_api_strict/tests/test_creation_functions.py,sha256=
|
|
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.
|
|
30
|
-
array_api_strict-1.
|
|
31
|
-
array_api_strict-1.
|
|
32
|
-
array_api_strict-1.
|
|
33
|
-
array_api_strict-1.
|
|
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,,
|
|
File without changes
|
|
File without changes
|