array-api-strict 2.3__py3-none-any.whl → 2.4__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/__init__.py +11 -5
- array_api_strict/_array_object.py +226 -200
- array_api_strict/_constants.py +1 -1
- array_api_strict/_creation_functions.py +97 -119
- array_api_strict/_data_type_functions.py +73 -64
- array_api_strict/_dtypes.py +35 -24
- array_api_strict/_elementwise_functions.py +138 -482
- array_api_strict/_fft.py +28 -32
- array_api_strict/_flags.py +65 -26
- array_api_strict/_helpers.py +23 -14
- array_api_strict/_indexing_functions.py +3 -8
- array_api_strict/_info.py +64 -69
- array_api_strict/_linalg.py +57 -53
- array_api_strict/_linear_algebra_functions.py +11 -9
- array_api_strict/_manipulation_functions.py +30 -30
- array_api_strict/_searching_functions.py +22 -33
- array_api_strict/_set_functions.py +4 -6
- array_api_strict/_sorting_functions.py +6 -6
- array_api_strict/_statistical_functions.py +57 -64
- array_api_strict/_typing.py +30 -50
- array_api_strict/_utility_functions.py +11 -13
- array_api_strict/_version.py +2 -2
- array_api_strict/py.typed +0 -0
- array_api_strict/tests/test_array_object.py +163 -56
- array_api_strict/tests/test_creation_functions.py +14 -12
- array_api_strict/tests/test_data_type_functions.py +40 -6
- array_api_strict/tests/test_elementwise_functions.py +94 -45
- array_api_strict/tests/test_searching_functions.py +79 -1
- array_api_strict/tests/test_validation.py +1 -3
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/METADATA +5 -4
- array_api_strict-2.4.dist-info/RECORD +44 -0
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/WHEEL +1 -1
- array_api_strict-2.3.dist-info/RECORD +0 -43
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/LICENSE +0 -0
- {array_api_strict-2.3.dist-info → array_api_strict-2.4.dist-info}/top_level.txt +0 -0
|
@@ -16,50 +16,51 @@ of ndarray.
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
import operator
|
|
19
|
+
from collections.abc import Iterator
|
|
19
20
|
from enum import IntEnum
|
|
21
|
+
from types import EllipsisType, ModuleType
|
|
22
|
+
from typing import Any, Final, Literal, SupportsIndex
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
import numpy as np
|
|
25
|
+
import numpy.typing as npt
|
|
26
|
+
|
|
27
|
+
from ._creation_functions import Undef, _undef, asarray
|
|
22
28
|
from ._dtypes import (
|
|
23
|
-
|
|
29
|
+
DType,
|
|
24
30
|
_all_dtypes,
|
|
25
31
|
_boolean_dtypes,
|
|
32
|
+
_complex_floating_dtypes,
|
|
33
|
+
_dtype_categories,
|
|
34
|
+
_floating_dtypes,
|
|
26
35
|
_integer_dtypes,
|
|
27
36
|
_integer_or_boolean_dtypes,
|
|
28
|
-
_floating_dtypes,
|
|
29
|
-
_real_floating_dtypes,
|
|
30
|
-
_complex_floating_dtypes,
|
|
31
37
|
_numeric_dtypes,
|
|
32
|
-
|
|
33
|
-
_dtype_categories,
|
|
38
|
+
_real_floating_dtypes,
|
|
34
39
|
_real_to_complex_map,
|
|
40
|
+
_result_type,
|
|
35
41
|
)
|
|
36
42
|
from ._flags import get_array_api_strict_flags, set_array_api_strict_flags
|
|
43
|
+
from ._typing import PyCapsule
|
|
37
44
|
|
|
38
|
-
from typing import TYPE_CHECKING, SupportsIndex
|
|
39
|
-
import types
|
|
40
|
-
|
|
41
|
-
if TYPE_CHECKING:
|
|
42
|
-
from typing import Optional, Tuple, Union, Any
|
|
43
|
-
from ._typing import PyCapsule, Dtype
|
|
44
|
-
import numpy.typing as npt
|
|
45
|
-
|
|
46
|
-
import numpy as np
|
|
47
45
|
|
|
48
46
|
class Device:
|
|
49
|
-
|
|
47
|
+
_device: Final[str]
|
|
48
|
+
__slots__ = ("_device", "__weakref__")
|
|
49
|
+
|
|
50
|
+
def __init__(self, device: str = "CPU_DEVICE"):
|
|
50
51
|
if device not in ("CPU_DEVICE", "device1", "device2"):
|
|
51
52
|
raise ValueError(f"The device '{device}' is not a valid choice.")
|
|
52
53
|
self._device = device
|
|
53
54
|
|
|
54
|
-
def __repr__(self):
|
|
55
|
+
def __repr__(self) -> str:
|
|
55
56
|
return f"array_api_strict.Device('{self._device}')"
|
|
56
57
|
|
|
57
|
-
def __eq__(self, other):
|
|
58
|
+
def __eq__(self, other: object) -> bool:
|
|
58
59
|
if not isinstance(other, Device):
|
|
59
60
|
return False
|
|
60
61
|
return self._device == other._device
|
|
61
62
|
|
|
62
|
-
def __hash__(self):
|
|
63
|
+
def __hash__(self) -> int:
|
|
63
64
|
return hash(("Device", self._device))
|
|
64
65
|
|
|
65
66
|
|
|
@@ -68,9 +69,6 @@ ALL_DEVICES = (CPU_DEVICE, Device("device1"), Device("device2"))
|
|
|
68
69
|
|
|
69
70
|
_default = object()
|
|
70
71
|
|
|
71
|
-
# See https://github.com/data-apis/array-api-strict/issues/67 and the comment
|
|
72
|
-
# on __array__ below.
|
|
73
|
-
_allow_array = True
|
|
74
72
|
|
|
75
73
|
class Array:
|
|
76
74
|
"""
|
|
@@ -87,12 +85,16 @@ class Array:
|
|
|
87
85
|
functions, such as asarray().
|
|
88
86
|
|
|
89
87
|
"""
|
|
88
|
+
|
|
90
89
|
_array: npt.NDArray[Any]
|
|
90
|
+
_dtype: DType
|
|
91
|
+
_device: Device
|
|
92
|
+
__slots__ = ("_array", "_dtype", "_device", "__weakref__")
|
|
91
93
|
|
|
92
94
|
# Use a custom constructor instead of __init__, as manually initializing
|
|
93
95
|
# this class is not supported API.
|
|
94
96
|
@classmethod
|
|
95
|
-
def _new(cls, x, /, device):
|
|
97
|
+
def _new(cls, x: npt.NDArray[Any] | np.generic, /, device: Device | None) -> Array:
|
|
96
98
|
"""
|
|
97
99
|
This is a private method for initializing the array API Array
|
|
98
100
|
object.
|
|
@@ -107,7 +109,7 @@ class Array:
|
|
|
107
109
|
if isinstance(x, np.generic):
|
|
108
110
|
# Convert the array scalar to a 0-D array
|
|
109
111
|
x = np.asarray(x)
|
|
110
|
-
_dtype =
|
|
112
|
+
_dtype = DType(x.dtype)
|
|
111
113
|
if _dtype not in _all_dtypes:
|
|
112
114
|
raise TypeError(
|
|
113
115
|
f"The array_api_strict namespace does not support the dtype '{x.dtype}'"
|
|
@@ -120,7 +122,7 @@ class Array:
|
|
|
120
122
|
return obj
|
|
121
123
|
|
|
122
124
|
# Prevent Array() from working
|
|
123
|
-
def __new__(cls, *args, **kwargs):
|
|
125
|
+
def __new__(cls, *args: object, **kwargs: object) -> Array:
|
|
124
126
|
raise TypeError(
|
|
125
127
|
"The array_api_strict Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead."
|
|
126
128
|
)
|
|
@@ -128,7 +130,7 @@ class Array:
|
|
|
128
130
|
# These functions are not required by the spec, but are implemented for
|
|
129
131
|
# the sake of usability.
|
|
130
132
|
|
|
131
|
-
def __repr__(self
|
|
133
|
+
def __repr__(self) -> str:
|
|
132
134
|
"""
|
|
133
135
|
Performs the operation __repr__.
|
|
134
136
|
"""
|
|
@@ -147,44 +149,36 @@ class Array:
|
|
|
147
149
|
|
|
148
150
|
__str__ = __repr__
|
|
149
151
|
|
|
150
|
-
#
|
|
151
|
-
# __array__. This means calling `np.func()` on an array_api_strict array
|
|
152
|
-
# will give an error. If we don't explicitly disallow it, NumPy defaults
|
|
153
|
-
# to creating an object dtype array, which would lead to confusing error
|
|
154
|
-
# messages at best and surprising bugs at worst. The reason for doing this
|
|
155
|
-
# is that __array__ is not actually supported by the standard, so it can
|
|
156
|
-
# lead to code assuming np.asarray(other_array) would always work in the
|
|
157
|
-
# standard.
|
|
158
|
-
#
|
|
159
|
-
# This was implemented historically for compatibility, and removing it has
|
|
152
|
+
# `__array__` was implemented historically for compatibility, and removing it has
|
|
160
153
|
# caused issues for some libraries (see
|
|
161
154
|
# https://github.com/data-apis/array-api-strict/issues/67).
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
raise ValueError("Conversion from an array_api_strict array to a NumPy ndarray is not supported")
|
|
155
|
+
|
|
156
|
+
# Instead of `__array__` we now implement the buffer protocol.
|
|
157
|
+
# Note that it makes array-apis-strict requiring python>=3.12
|
|
158
|
+
def __buffer__(self, flags):
|
|
159
|
+
if self._device != CPU_DEVICE:
|
|
160
|
+
raise RuntimeError(f"Can not convert array on the '{self._device}' device to a Numpy array.")
|
|
161
|
+
return self._array.__buffer__(flags)
|
|
162
|
+
|
|
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:
|
|
171
|
+
raise TypeError(
|
|
172
|
+
"Interoperation with NumPy requires python >= 3.12. Please upgrade."
|
|
173
|
+
)
|
|
182
174
|
|
|
183
175
|
# These are various helper functions to make the array behavior match the
|
|
184
176
|
# spec in places where it either deviates from or is more strict than
|
|
185
177
|
# NumPy behavior
|
|
186
178
|
|
|
187
|
-
def _check_allowed_dtypes(
|
|
179
|
+
def _check_allowed_dtypes(
|
|
180
|
+
self, other: Array | complex, dtype_category: str, op: str
|
|
181
|
+
) -> Array:
|
|
188
182
|
"""
|
|
189
183
|
Helper function for operators to only allow specific input dtypes
|
|
190
184
|
|
|
@@ -197,7 +191,7 @@ class Array:
|
|
|
197
191
|
|
|
198
192
|
if self.dtype not in _dtype_categories[dtype_category]:
|
|
199
193
|
raise TypeError(f"Only {dtype_category} dtypes are allowed in {op}")
|
|
200
|
-
if isinstance(other, (
|
|
194
|
+
if isinstance(other, (bool, int, float, complex)):
|
|
201
195
|
other = self._promote_scalar(other)
|
|
202
196
|
elif isinstance(other, Array):
|
|
203
197
|
if other.dtype not in _dtype_categories[dtype_category]:
|
|
@@ -225,16 +219,19 @@ class Array:
|
|
|
225
219
|
|
|
226
220
|
return other
|
|
227
221
|
|
|
228
|
-
def
|
|
229
|
-
"""Check that other is
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
222
|
+
def _check_type_device(self, other: Array | complex) -> None:
|
|
223
|
+
"""Check that other is either a Python scalar or an array on a device
|
|
224
|
+
compatible with the current array.
|
|
225
|
+
"""
|
|
226
|
+
if isinstance(other, Array):
|
|
233
227
|
if self.device != other.device:
|
|
234
228
|
raise ValueError(f"Arrays from two different devices ({self.device} and {other.device}) can not be combined.")
|
|
229
|
+
# Disallow subclasses of Python scalars, such as np.float64 and np.complex128
|
|
230
|
+
elif type(other) not in (bool, int, float, complex):
|
|
231
|
+
raise TypeError(f"Expected Array or Python scalar; got {type(other)}")
|
|
235
232
|
|
|
236
233
|
# Helper function to match the type promotion rules in the spec
|
|
237
|
-
def _promote_scalar(self, scalar):
|
|
234
|
+
def _promote_scalar(self, scalar: complex) -> Array:
|
|
238
235
|
"""
|
|
239
236
|
Returns a promoted version of a Python scalar appropriate for use with
|
|
240
237
|
operations on self.
|
|
@@ -291,7 +288,7 @@ class Array:
|
|
|
291
288
|
return Array._new(np.array(scalar, dtype=target_dtype._np_dtype), device=self.device)
|
|
292
289
|
|
|
293
290
|
@staticmethod
|
|
294
|
-
def _normalize_two_args(x1, x2) ->
|
|
291
|
+
def _normalize_two_args(x1: Array, x2: Array) -> tuple[Array, Array]:
|
|
295
292
|
"""
|
|
296
293
|
Normalize inputs to two arg functions to fix type promotion rules
|
|
297
294
|
|
|
@@ -327,7 +324,17 @@ class Array:
|
|
|
327
324
|
|
|
328
325
|
# Note: A large fraction of allowed indices are disallowed here (see the
|
|
329
326
|
# docstring below)
|
|
330
|
-
def _validate_index(
|
|
327
|
+
def _validate_index(
|
|
328
|
+
self,
|
|
329
|
+
key: (
|
|
330
|
+
int
|
|
331
|
+
| slice
|
|
332
|
+
| EllipsisType
|
|
333
|
+
| Array
|
|
334
|
+
| tuple[int | slice | EllipsisType | Array | None, ...]
|
|
335
|
+
),
|
|
336
|
+
op: Literal["getitem", "setitem"] = "getitem",
|
|
337
|
+
) -> None:
|
|
331
338
|
"""
|
|
332
339
|
Validate an index according to the array API.
|
|
333
340
|
|
|
@@ -509,7 +516,7 @@ class Array:
|
|
|
509
516
|
|
|
510
517
|
# Everything below this line is required by the spec.
|
|
511
518
|
|
|
512
|
-
def __abs__(self
|
|
519
|
+
def __abs__(self) -> Array:
|
|
513
520
|
"""
|
|
514
521
|
Performs the operation __abs__.
|
|
515
522
|
"""
|
|
@@ -518,11 +525,11 @@ class Array:
|
|
|
518
525
|
res = self._array.__abs__()
|
|
519
526
|
return self.__class__._new(res, device=self.device)
|
|
520
527
|
|
|
521
|
-
def __add__(self
|
|
528
|
+
def __add__(self, other: Array | complex, /) -> Array:
|
|
522
529
|
"""
|
|
523
530
|
Performs the operation __add__.
|
|
524
531
|
"""
|
|
525
|
-
self.
|
|
532
|
+
self._check_type_device(other)
|
|
526
533
|
other = self._check_allowed_dtypes(other, "numeric", "__add__")
|
|
527
534
|
if other is NotImplemented:
|
|
528
535
|
return other
|
|
@@ -530,11 +537,11 @@ class Array:
|
|
|
530
537
|
res = self._array.__add__(other._array)
|
|
531
538
|
return self.__class__._new(res, device=self.device)
|
|
532
539
|
|
|
533
|
-
def __and__(self
|
|
540
|
+
def __and__(self, other: Array | int, /) -> Array:
|
|
534
541
|
"""
|
|
535
542
|
Performs the operation __and__.
|
|
536
543
|
"""
|
|
537
|
-
self.
|
|
544
|
+
self._check_type_device(other)
|
|
538
545
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__and__")
|
|
539
546
|
if other is NotImplemented:
|
|
540
547
|
return other
|
|
@@ -542,9 +549,7 @@ class Array:
|
|
|
542
549
|
res = self._array.__and__(other._array)
|
|
543
550
|
return self.__class__._new(res, device=self.device)
|
|
544
551
|
|
|
545
|
-
def __array_namespace__(
|
|
546
|
-
self: Array, /, *, api_version: Optional[str] = None
|
|
547
|
-
) -> types.ModuleType:
|
|
552
|
+
def __array_namespace__(self, /, *, api_version: str | None = None) -> ModuleType:
|
|
548
553
|
"""
|
|
549
554
|
Return the array_api_strict namespace corresponding to api_version.
|
|
550
555
|
|
|
@@ -563,7 +568,7 @@ class Array:
|
|
|
563
568
|
import array_api_strict
|
|
564
569
|
return array_api_strict
|
|
565
570
|
|
|
566
|
-
def __bool__(self
|
|
571
|
+
def __bool__(self) -> bool:
|
|
567
572
|
"""
|
|
568
573
|
Performs the operation __bool__.
|
|
569
574
|
"""
|
|
@@ -573,7 +578,7 @@ class Array:
|
|
|
573
578
|
res = self._array.__bool__()
|
|
574
579
|
return res
|
|
575
580
|
|
|
576
|
-
def __complex__(self
|
|
581
|
+
def __complex__(self) -> complex:
|
|
577
582
|
"""
|
|
578
583
|
Performs the operation __complex__.
|
|
579
584
|
"""
|
|
@@ -584,56 +589,56 @@ class Array:
|
|
|
584
589
|
return res
|
|
585
590
|
|
|
586
591
|
def __dlpack__(
|
|
587
|
-
self
|
|
592
|
+
self,
|
|
588
593
|
/,
|
|
589
594
|
*,
|
|
590
|
-
stream:
|
|
591
|
-
max_version:
|
|
592
|
-
dl_device:
|
|
593
|
-
copy:
|
|
595
|
+
stream: Any = None,
|
|
596
|
+
max_version: tuple[int, int] | None | Undef = _undef,
|
|
597
|
+
dl_device: tuple[IntEnum, int] | None | Undef = _undef,
|
|
598
|
+
copy: bool | None | Undef = _undef,
|
|
594
599
|
) -> PyCapsule:
|
|
595
600
|
"""
|
|
596
601
|
Performs the operation __dlpack__.
|
|
597
602
|
"""
|
|
598
603
|
if get_array_api_strict_flags()['api_version'] < '2023.12':
|
|
599
|
-
if max_version is not
|
|
604
|
+
if max_version is not _undef:
|
|
600
605
|
raise ValueError("The max_version argument to __dlpack__ requires at least version 2023.12 of the array API")
|
|
601
|
-
if dl_device is not
|
|
606
|
+
if dl_device is not _undef:
|
|
602
607
|
raise ValueError("The device argument to __dlpack__ requires at least version 2023.12 of the array API")
|
|
603
|
-
if copy is not
|
|
608
|
+
if copy is not _undef:
|
|
604
609
|
raise ValueError("The copy argument to __dlpack__ requires at least version 2023.12 of the array API")
|
|
605
610
|
|
|
606
611
|
if np.lib.NumpyVersion(np.__version__) < '2.1.0':
|
|
607
|
-
if max_version not in [
|
|
612
|
+
if max_version not in [_undef, None]:
|
|
608
613
|
raise NotImplementedError("The max_version argument to __dlpack__ is not yet implemented")
|
|
609
|
-
if dl_device not in [
|
|
614
|
+
if dl_device not in [_undef, None]:
|
|
610
615
|
raise NotImplementedError("The device argument to __dlpack__ is not yet implemented")
|
|
611
|
-
if copy not in [
|
|
616
|
+
if copy not in [_undef, None]:
|
|
612
617
|
raise NotImplementedError("The copy argument to __dlpack__ is not yet implemented")
|
|
613
618
|
|
|
614
619
|
return self._array.__dlpack__(stream=stream)
|
|
615
620
|
else:
|
|
616
621
|
kwargs = {'stream': stream}
|
|
617
|
-
if max_version is not
|
|
622
|
+
if max_version is not _undef:
|
|
618
623
|
kwargs['max_version'] = max_version
|
|
619
|
-
if dl_device is not
|
|
624
|
+
if dl_device is not _undef:
|
|
620
625
|
kwargs['dl_device'] = dl_device
|
|
621
|
-
if copy is not
|
|
626
|
+
if copy is not _undef:
|
|
622
627
|
kwargs['copy'] = copy
|
|
623
628
|
return self._array.__dlpack__(**kwargs)
|
|
624
629
|
|
|
625
|
-
def __dlpack_device__(self
|
|
630
|
+
def __dlpack_device__(self) -> tuple[IntEnum, int]:
|
|
626
631
|
"""
|
|
627
632
|
Performs the operation __dlpack_device__.
|
|
628
633
|
"""
|
|
629
634
|
# Note: device support is required for this
|
|
630
635
|
return self._array.__dlpack_device__()
|
|
631
636
|
|
|
632
|
-
def __eq__(self
|
|
637
|
+
def __eq__(self, other: Array | complex, /) -> Array: # type: ignore[override]
|
|
633
638
|
"""
|
|
634
639
|
Performs the operation __eq__.
|
|
635
640
|
"""
|
|
636
|
-
self.
|
|
641
|
+
self._check_type_device(other)
|
|
637
642
|
# Even though "all" dtypes are allowed, we still require them to be
|
|
638
643
|
# promotable with each other.
|
|
639
644
|
other = self._check_allowed_dtypes(other, "all", "__eq__")
|
|
@@ -643,7 +648,7 @@ class Array:
|
|
|
643
648
|
res = self._array.__eq__(other._array)
|
|
644
649
|
return self.__class__._new(res, device=self.device)
|
|
645
650
|
|
|
646
|
-
def __float__(self
|
|
651
|
+
def __float__(self) -> float:
|
|
647
652
|
"""
|
|
648
653
|
Performs the operation __float__.
|
|
649
654
|
"""
|
|
@@ -655,11 +660,11 @@ class Array:
|
|
|
655
660
|
res = self._array.__float__()
|
|
656
661
|
return res
|
|
657
662
|
|
|
658
|
-
def __floordiv__(self
|
|
663
|
+
def __floordiv__(self, other: Array | float, /) -> Array:
|
|
659
664
|
"""
|
|
660
665
|
Performs the operation __floordiv__.
|
|
661
666
|
"""
|
|
662
|
-
self.
|
|
667
|
+
self._check_type_device(other)
|
|
663
668
|
other = self._check_allowed_dtypes(other, "real numeric", "__floordiv__")
|
|
664
669
|
if other is NotImplemented:
|
|
665
670
|
return other
|
|
@@ -667,11 +672,11 @@ class Array:
|
|
|
667
672
|
res = self._array.__floordiv__(other._array)
|
|
668
673
|
return self.__class__._new(res, device=self.device)
|
|
669
674
|
|
|
670
|
-
def __ge__(self
|
|
675
|
+
def __ge__(self, other: Array | float, /) -> Array:
|
|
671
676
|
"""
|
|
672
677
|
Performs the operation __ge__.
|
|
673
678
|
"""
|
|
674
|
-
self.
|
|
679
|
+
self._check_type_device(other)
|
|
675
680
|
other = self._check_allowed_dtypes(other, "real numeric", "__ge__")
|
|
676
681
|
if other is NotImplemented:
|
|
677
682
|
return other
|
|
@@ -680,14 +685,15 @@ class Array:
|
|
|
680
685
|
return self.__class__._new(res, device=self.device)
|
|
681
686
|
|
|
682
687
|
def __getitem__(
|
|
683
|
-
self
|
|
684
|
-
key:
|
|
685
|
-
int
|
|
686
|
-
slice
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
688
|
+
self,
|
|
689
|
+
key: (
|
|
690
|
+
int
|
|
691
|
+
| slice
|
|
692
|
+
| EllipsisType
|
|
693
|
+
| Array
|
|
694
|
+
| None
|
|
695
|
+
| tuple[int | slice | EllipsisType | Array | None, ...]
|
|
696
|
+
),
|
|
691
697
|
/,
|
|
692
698
|
) -> Array:
|
|
693
699
|
"""
|
|
@@ -696,18 +702,33 @@ class Array:
|
|
|
696
702
|
# XXX Does key have to be on the same device? Is there an exception for CPU_DEVICE?
|
|
697
703
|
# Note: Only indices required by the spec are allowed. See the
|
|
698
704
|
# docstring of _validate_index
|
|
699
|
-
self._validate_index(key)
|
|
705
|
+
self._validate_index(key, op="getitem")
|
|
700
706
|
if isinstance(key, Array):
|
|
707
|
+
key = (key,)
|
|
708
|
+
np_key = key
|
|
709
|
+
devices = {self.device}
|
|
710
|
+
if isinstance(key, tuple):
|
|
711
|
+
devices.update(
|
|
712
|
+
[subkey.device for subkey in key if isinstance(subkey, Array)]
|
|
713
|
+
)
|
|
714
|
+
if len(devices) > 1:
|
|
715
|
+
raise ValueError(
|
|
716
|
+
"Array indexing is only allowed when array to be indexed and all "
|
|
717
|
+
"indexing arrays are on the same device."
|
|
718
|
+
)
|
|
701
719
|
# Indexing self._array with array_api_strict arrays can be erroneous
|
|
702
|
-
|
|
703
|
-
|
|
720
|
+
# e.g., when using non-default device
|
|
721
|
+
np_key = tuple(
|
|
722
|
+
subkey._array if isinstance(subkey, Array) else subkey for subkey in key
|
|
723
|
+
)
|
|
724
|
+
res = self._array.__getitem__(np_key)
|
|
704
725
|
return self._new(res, device=self.device)
|
|
705
726
|
|
|
706
|
-
def __gt__(self
|
|
727
|
+
def __gt__(self, other: Array | float, /) -> Array:
|
|
707
728
|
"""
|
|
708
729
|
Performs the operation __gt__.
|
|
709
730
|
"""
|
|
710
|
-
self.
|
|
731
|
+
self._check_type_device(other)
|
|
711
732
|
other = self._check_allowed_dtypes(other, "real numeric", "__gt__")
|
|
712
733
|
if other is NotImplemented:
|
|
713
734
|
return other
|
|
@@ -715,7 +736,7 @@ class Array:
|
|
|
715
736
|
res = self._array.__gt__(other._array)
|
|
716
737
|
return self.__class__._new(res, device=other.device)
|
|
717
738
|
|
|
718
|
-
def __int__(self
|
|
739
|
+
def __int__(self) -> int:
|
|
719
740
|
"""
|
|
720
741
|
Performs the operation __int__.
|
|
721
742
|
"""
|
|
@@ -727,14 +748,14 @@ class Array:
|
|
|
727
748
|
res = self._array.__int__()
|
|
728
749
|
return res
|
|
729
750
|
|
|
730
|
-
def __index__(self
|
|
751
|
+
def __index__(self) -> int:
|
|
731
752
|
"""
|
|
732
753
|
Performs the operation __index__.
|
|
733
754
|
"""
|
|
734
755
|
res = self._array.__index__()
|
|
735
756
|
return res
|
|
736
757
|
|
|
737
|
-
def __invert__(self
|
|
758
|
+
def __invert__(self) -> Array:
|
|
738
759
|
"""
|
|
739
760
|
Performs the operation __invert__.
|
|
740
761
|
"""
|
|
@@ -743,7 +764,7 @@ class Array:
|
|
|
743
764
|
res = self._array.__invert__()
|
|
744
765
|
return self.__class__._new(res, device=self.device)
|
|
745
766
|
|
|
746
|
-
def __iter__(self
|
|
767
|
+
def __iter__(self) -> Iterator[Array]:
|
|
747
768
|
"""
|
|
748
769
|
Performs the operation __iter__.
|
|
749
770
|
"""
|
|
@@ -758,11 +779,11 @@ class Array:
|
|
|
758
779
|
# implemented, which implies iteration on 1-D arrays.
|
|
759
780
|
return (Array._new(i, device=self.device) for i in self._array)
|
|
760
781
|
|
|
761
|
-
def __le__(self
|
|
782
|
+
def __le__(self, other: Array | float, /) -> Array:
|
|
762
783
|
"""
|
|
763
784
|
Performs the operation __le__.
|
|
764
785
|
"""
|
|
765
|
-
self.
|
|
786
|
+
self._check_type_device(other)
|
|
766
787
|
other = self._check_allowed_dtypes(other, "real numeric", "__le__")
|
|
767
788
|
if other is NotImplemented:
|
|
768
789
|
return other
|
|
@@ -770,11 +791,11 @@ class Array:
|
|
|
770
791
|
res = self._array.__le__(other._array)
|
|
771
792
|
return self.__class__._new(res, device=self.device)
|
|
772
793
|
|
|
773
|
-
def __lshift__(self
|
|
794
|
+
def __lshift__(self, other: Array | int, /) -> Array:
|
|
774
795
|
"""
|
|
775
796
|
Performs the operation __lshift__.
|
|
776
797
|
"""
|
|
777
|
-
self.
|
|
798
|
+
self._check_type_device(other)
|
|
778
799
|
other = self._check_allowed_dtypes(other, "integer", "__lshift__")
|
|
779
800
|
if other is NotImplemented:
|
|
780
801
|
return other
|
|
@@ -782,11 +803,11 @@ class Array:
|
|
|
782
803
|
res = self._array.__lshift__(other._array)
|
|
783
804
|
return self.__class__._new(res, device=self.device)
|
|
784
805
|
|
|
785
|
-
def __lt__(self
|
|
806
|
+
def __lt__(self, other: Array | float, /) -> Array:
|
|
786
807
|
"""
|
|
787
808
|
Performs the operation __lt__.
|
|
788
809
|
"""
|
|
789
|
-
self.
|
|
810
|
+
self._check_type_device(other)
|
|
790
811
|
other = self._check_allowed_dtypes(other, "real numeric", "__lt__")
|
|
791
812
|
if other is NotImplemented:
|
|
792
813
|
return other
|
|
@@ -794,11 +815,11 @@ class Array:
|
|
|
794
815
|
res = self._array.__lt__(other._array)
|
|
795
816
|
return self.__class__._new(res, device=self.device)
|
|
796
817
|
|
|
797
|
-
def __matmul__(self
|
|
818
|
+
def __matmul__(self, other: Array, /) -> Array:
|
|
798
819
|
"""
|
|
799
820
|
Performs the operation __matmul__.
|
|
800
821
|
"""
|
|
801
|
-
self.
|
|
822
|
+
self._check_type_device(other)
|
|
802
823
|
# matmul is not defined for scalars, but without this, we may get
|
|
803
824
|
# the wrong error message from asarray.
|
|
804
825
|
other = self._check_allowed_dtypes(other, "numeric", "__matmul__")
|
|
@@ -807,11 +828,11 @@ class Array:
|
|
|
807
828
|
res = self._array.__matmul__(other._array)
|
|
808
829
|
return self.__class__._new(res, device=self.device)
|
|
809
830
|
|
|
810
|
-
def __mod__(self
|
|
831
|
+
def __mod__(self, other: Array | float, /) -> Array:
|
|
811
832
|
"""
|
|
812
833
|
Performs the operation __mod__.
|
|
813
834
|
"""
|
|
814
|
-
self.
|
|
835
|
+
self._check_type_device(other)
|
|
815
836
|
other = self._check_allowed_dtypes(other, "real numeric", "__mod__")
|
|
816
837
|
if other is NotImplemented:
|
|
817
838
|
return other
|
|
@@ -819,11 +840,11 @@ class Array:
|
|
|
819
840
|
res = self._array.__mod__(other._array)
|
|
820
841
|
return self.__class__._new(res, device=self.device)
|
|
821
842
|
|
|
822
|
-
def __mul__(self
|
|
843
|
+
def __mul__(self, other: Array | complex, /) -> Array:
|
|
823
844
|
"""
|
|
824
845
|
Performs the operation __mul__.
|
|
825
846
|
"""
|
|
826
|
-
self.
|
|
847
|
+
self._check_type_device(other)
|
|
827
848
|
other = self._check_allowed_dtypes(other, "numeric", "__mul__")
|
|
828
849
|
if other is NotImplemented:
|
|
829
850
|
return other
|
|
@@ -831,11 +852,11 @@ class Array:
|
|
|
831
852
|
res = self._array.__mul__(other._array)
|
|
832
853
|
return self.__class__._new(res, device=self.device)
|
|
833
854
|
|
|
834
|
-
def __ne__(self
|
|
855
|
+
def __ne__(self, other: Array | complex, /) -> Array: # type: ignore[override]
|
|
835
856
|
"""
|
|
836
857
|
Performs the operation __ne__.
|
|
837
858
|
"""
|
|
838
|
-
self.
|
|
859
|
+
self._check_type_device(other)
|
|
839
860
|
other = self._check_allowed_dtypes(other, "all", "__ne__")
|
|
840
861
|
if other is NotImplemented:
|
|
841
862
|
return other
|
|
@@ -843,7 +864,7 @@ class Array:
|
|
|
843
864
|
res = self._array.__ne__(other._array)
|
|
844
865
|
return self.__class__._new(res, device=self.device)
|
|
845
866
|
|
|
846
|
-
def __neg__(self
|
|
867
|
+
def __neg__(self) -> Array:
|
|
847
868
|
"""
|
|
848
869
|
Performs the operation __neg__.
|
|
849
870
|
"""
|
|
@@ -852,11 +873,11 @@ class Array:
|
|
|
852
873
|
res = self._array.__neg__()
|
|
853
874
|
return self.__class__._new(res, device=self.device)
|
|
854
875
|
|
|
855
|
-
def __or__(self
|
|
876
|
+
def __or__(self, other: Array | int, /) -> Array:
|
|
856
877
|
"""
|
|
857
878
|
Performs the operation __or__.
|
|
858
879
|
"""
|
|
859
|
-
self.
|
|
880
|
+
self._check_type_device(other)
|
|
860
881
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__or__")
|
|
861
882
|
if other is NotImplemented:
|
|
862
883
|
return other
|
|
@@ -864,7 +885,7 @@ class Array:
|
|
|
864
885
|
res = self._array.__or__(other._array)
|
|
865
886
|
return self.__class__._new(res, device=self.device)
|
|
866
887
|
|
|
867
|
-
def __pos__(self
|
|
888
|
+
def __pos__(self) -> Array:
|
|
868
889
|
"""
|
|
869
890
|
Performs the operation __pos__.
|
|
870
891
|
"""
|
|
@@ -873,13 +894,13 @@ class Array:
|
|
|
873
894
|
res = self._array.__pos__()
|
|
874
895
|
return self.__class__._new(res, device=self.device)
|
|
875
896
|
|
|
876
|
-
def __pow__(self
|
|
897
|
+
def __pow__(self, other: Array | complex, /) -> Array:
|
|
877
898
|
"""
|
|
878
899
|
Performs the operation __pow__.
|
|
879
900
|
"""
|
|
880
|
-
from ._elementwise_functions import pow
|
|
901
|
+
from ._elementwise_functions import pow # type: ignore[attr-defined]
|
|
881
902
|
|
|
882
|
-
self.
|
|
903
|
+
self._check_type_device(other)
|
|
883
904
|
other = self._check_allowed_dtypes(other, "numeric", "__pow__")
|
|
884
905
|
if other is NotImplemented:
|
|
885
906
|
return other
|
|
@@ -887,11 +908,11 @@ class Array:
|
|
|
887
908
|
# arrays, so we use pow() here instead.
|
|
888
909
|
return pow(self, other)
|
|
889
910
|
|
|
890
|
-
def __rshift__(self
|
|
911
|
+
def __rshift__(self, other: Array | int, /) -> Array:
|
|
891
912
|
"""
|
|
892
913
|
Performs the operation __rshift__.
|
|
893
914
|
"""
|
|
894
|
-
self.
|
|
915
|
+
self._check_type_device(other)
|
|
895
916
|
other = self._check_allowed_dtypes(other, "integer", "__rshift__")
|
|
896
917
|
if other is NotImplemented:
|
|
897
918
|
return other
|
|
@@ -901,10 +922,16 @@ class Array:
|
|
|
901
922
|
|
|
902
923
|
def __setitem__(
|
|
903
924
|
self,
|
|
904
|
-
key
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
925
|
+
# Almost same as __getitem__ key but doesn't accept None
|
|
926
|
+
# or integer arrays
|
|
927
|
+
key: (
|
|
928
|
+
int
|
|
929
|
+
| slice
|
|
930
|
+
| EllipsisType
|
|
931
|
+
| Array
|
|
932
|
+
| tuple[int | slice | EllipsisType, ...]
|
|
933
|
+
),
|
|
934
|
+
value: Array | complex,
|
|
908
935
|
/,
|
|
909
936
|
) -> None:
|
|
910
937
|
"""
|
|
@@ -913,16 +940,15 @@ class Array:
|
|
|
913
940
|
# Note: Only indices required by the spec are allowed. See the
|
|
914
941
|
# docstring of _validate_index
|
|
915
942
|
self._validate_index(key, op="setitem")
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
self._array.__setitem__(key, asarray(value)._array)
|
|
943
|
+
# Indexing self._array with array_api_strict arrays can be erroneous
|
|
944
|
+
np_key = key._array if isinstance(key, Array) else key
|
|
945
|
+
self._array.__setitem__(np_key, asarray(value)._array)
|
|
920
946
|
|
|
921
|
-
def __sub__(self
|
|
947
|
+
def __sub__(self, other: Array | complex, /) -> Array:
|
|
922
948
|
"""
|
|
923
949
|
Performs the operation __sub__.
|
|
924
950
|
"""
|
|
925
|
-
self.
|
|
951
|
+
self._check_type_device(other)
|
|
926
952
|
other = self._check_allowed_dtypes(other, "numeric", "__sub__")
|
|
927
953
|
if other is NotImplemented:
|
|
928
954
|
return other
|
|
@@ -932,11 +958,11 @@ class Array:
|
|
|
932
958
|
|
|
933
959
|
# PEP 484 requires int to be a subtype of float, but __truediv__ should
|
|
934
960
|
# not accept int.
|
|
935
|
-
def __truediv__(self
|
|
961
|
+
def __truediv__(self, other: Array | complex, /) -> Array:
|
|
936
962
|
"""
|
|
937
963
|
Performs the operation __truediv__.
|
|
938
964
|
"""
|
|
939
|
-
self.
|
|
965
|
+
self._check_type_device(other)
|
|
940
966
|
other = self._check_allowed_dtypes(other, "floating-point", "__truediv__")
|
|
941
967
|
if other is NotImplemented:
|
|
942
968
|
return other
|
|
@@ -944,11 +970,11 @@ class Array:
|
|
|
944
970
|
res = self._array.__truediv__(other._array)
|
|
945
971
|
return self.__class__._new(res, device=self.device)
|
|
946
972
|
|
|
947
|
-
def __xor__(self
|
|
973
|
+
def __xor__(self, other: Array | int, /) -> Array:
|
|
948
974
|
"""
|
|
949
975
|
Performs the operation __xor__.
|
|
950
976
|
"""
|
|
951
|
-
self.
|
|
977
|
+
self._check_type_device(other)
|
|
952
978
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__xor__")
|
|
953
979
|
if other is NotImplemented:
|
|
954
980
|
return other
|
|
@@ -956,22 +982,22 @@ class Array:
|
|
|
956
982
|
res = self._array.__xor__(other._array)
|
|
957
983
|
return self.__class__._new(res, device=self.device)
|
|
958
984
|
|
|
959
|
-
def __iadd__(self
|
|
985
|
+
def __iadd__(self, other: Array | complex, /) -> Array:
|
|
960
986
|
"""
|
|
961
987
|
Performs the operation __iadd__.
|
|
962
988
|
"""
|
|
963
|
-
self.
|
|
989
|
+
self._check_type_device(other)
|
|
964
990
|
other = self._check_allowed_dtypes(other, "numeric", "__iadd__")
|
|
965
991
|
if other is NotImplemented:
|
|
966
992
|
return other
|
|
967
993
|
self._array.__iadd__(other._array)
|
|
968
994
|
return self
|
|
969
995
|
|
|
970
|
-
def __radd__(self
|
|
996
|
+
def __radd__(self, other: Array | complex, /) -> Array:
|
|
971
997
|
"""
|
|
972
998
|
Performs the operation __radd__.
|
|
973
999
|
"""
|
|
974
|
-
self.
|
|
1000
|
+
self._check_type_device(other)
|
|
975
1001
|
other = self._check_allowed_dtypes(other, "numeric", "__radd__")
|
|
976
1002
|
if other is NotImplemented:
|
|
977
1003
|
return other
|
|
@@ -979,22 +1005,22 @@ class Array:
|
|
|
979
1005
|
res = self._array.__radd__(other._array)
|
|
980
1006
|
return self.__class__._new(res, device=self.device)
|
|
981
1007
|
|
|
982
|
-
def __iand__(self
|
|
1008
|
+
def __iand__(self, other: Array | int, /) -> Array:
|
|
983
1009
|
"""
|
|
984
1010
|
Performs the operation __iand__.
|
|
985
1011
|
"""
|
|
986
|
-
self.
|
|
1012
|
+
self._check_type_device(other)
|
|
987
1013
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__iand__")
|
|
988
1014
|
if other is NotImplemented:
|
|
989
1015
|
return other
|
|
990
1016
|
self._array.__iand__(other._array)
|
|
991
1017
|
return self
|
|
992
1018
|
|
|
993
|
-
def __rand__(self
|
|
1019
|
+
def __rand__(self, other: Array | int, /) -> Array:
|
|
994
1020
|
"""
|
|
995
1021
|
Performs the operation __rand__.
|
|
996
1022
|
"""
|
|
997
|
-
self.
|
|
1023
|
+
self._check_type_device(other)
|
|
998
1024
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__rand__")
|
|
999
1025
|
if other is NotImplemented:
|
|
1000
1026
|
return other
|
|
@@ -1002,22 +1028,22 @@ class Array:
|
|
|
1002
1028
|
res = self._array.__rand__(other._array)
|
|
1003
1029
|
return self.__class__._new(res, device=self.device)
|
|
1004
1030
|
|
|
1005
|
-
def __ifloordiv__(self
|
|
1031
|
+
def __ifloordiv__(self, other: Array | float, /) -> Array:
|
|
1006
1032
|
"""
|
|
1007
1033
|
Performs the operation __ifloordiv__.
|
|
1008
1034
|
"""
|
|
1009
|
-
self.
|
|
1035
|
+
self._check_type_device(other)
|
|
1010
1036
|
other = self._check_allowed_dtypes(other, "real numeric", "__ifloordiv__")
|
|
1011
1037
|
if other is NotImplemented:
|
|
1012
1038
|
return other
|
|
1013
1039
|
self._array.__ifloordiv__(other._array)
|
|
1014
1040
|
return self
|
|
1015
1041
|
|
|
1016
|
-
def __rfloordiv__(self
|
|
1042
|
+
def __rfloordiv__(self, other: Array | float, /) -> Array:
|
|
1017
1043
|
"""
|
|
1018
1044
|
Performs the operation __rfloordiv__.
|
|
1019
1045
|
"""
|
|
1020
|
-
self.
|
|
1046
|
+
self._check_type_device(other)
|
|
1021
1047
|
other = self._check_allowed_dtypes(other, "real numeric", "__rfloordiv__")
|
|
1022
1048
|
if other is NotImplemented:
|
|
1023
1049
|
return other
|
|
@@ -1025,22 +1051,22 @@ class Array:
|
|
|
1025
1051
|
res = self._array.__rfloordiv__(other._array)
|
|
1026
1052
|
return self.__class__._new(res, device=self.device)
|
|
1027
1053
|
|
|
1028
|
-
def __ilshift__(self
|
|
1054
|
+
def __ilshift__(self, other: Array | int, /) -> Array:
|
|
1029
1055
|
"""
|
|
1030
1056
|
Performs the operation __ilshift__.
|
|
1031
1057
|
"""
|
|
1032
|
-
self.
|
|
1058
|
+
self._check_type_device(other)
|
|
1033
1059
|
other = self._check_allowed_dtypes(other, "integer", "__ilshift__")
|
|
1034
1060
|
if other is NotImplemented:
|
|
1035
1061
|
return other
|
|
1036
1062
|
self._array.__ilshift__(other._array)
|
|
1037
1063
|
return self
|
|
1038
1064
|
|
|
1039
|
-
def __rlshift__(self
|
|
1065
|
+
def __rlshift__(self, other: Array | int, /) -> Array:
|
|
1040
1066
|
"""
|
|
1041
1067
|
Performs the operation __rlshift__.
|
|
1042
1068
|
"""
|
|
1043
|
-
self.
|
|
1069
|
+
self._check_type_device(other)
|
|
1044
1070
|
other = self._check_allowed_dtypes(other, "integer", "__rlshift__")
|
|
1045
1071
|
if other is NotImplemented:
|
|
1046
1072
|
return other
|
|
@@ -1048,7 +1074,7 @@ class Array:
|
|
|
1048
1074
|
res = self._array.__rlshift__(other._array)
|
|
1049
1075
|
return self.__class__._new(res, device=self.device)
|
|
1050
1076
|
|
|
1051
|
-
def __imatmul__(self
|
|
1077
|
+
def __imatmul__(self, other: Array, /) -> Array:
|
|
1052
1078
|
"""
|
|
1053
1079
|
Performs the operation __imatmul__.
|
|
1054
1080
|
"""
|
|
@@ -1057,11 +1083,11 @@ class Array:
|
|
|
1057
1083
|
other = self._check_allowed_dtypes(other, "numeric", "__imatmul__")
|
|
1058
1084
|
if other is NotImplemented:
|
|
1059
1085
|
return other
|
|
1060
|
-
self.
|
|
1086
|
+
self._check_type_device(other)
|
|
1061
1087
|
res = self._array.__imatmul__(other._array)
|
|
1062
1088
|
return self.__class__._new(res, device=self.device)
|
|
1063
1089
|
|
|
1064
|
-
def __rmatmul__(self
|
|
1090
|
+
def __rmatmul__(self, other: Array, /) -> Array:
|
|
1065
1091
|
"""
|
|
1066
1092
|
Performs the operation __rmatmul__.
|
|
1067
1093
|
"""
|
|
@@ -1070,11 +1096,11 @@ class Array:
|
|
|
1070
1096
|
other = self._check_allowed_dtypes(other, "numeric", "__rmatmul__")
|
|
1071
1097
|
if other is NotImplemented:
|
|
1072
1098
|
return other
|
|
1073
|
-
self.
|
|
1099
|
+
self._check_type_device(other)
|
|
1074
1100
|
res = self._array.__rmatmul__(other._array)
|
|
1075
1101
|
return self.__class__._new(res, device=self.device)
|
|
1076
1102
|
|
|
1077
|
-
def __imod__(self
|
|
1103
|
+
def __imod__(self, other: Array | float, /) -> Array:
|
|
1078
1104
|
"""
|
|
1079
1105
|
Performs the operation __imod__.
|
|
1080
1106
|
"""
|
|
@@ -1084,19 +1110,19 @@ class Array:
|
|
|
1084
1110
|
self._array.__imod__(other._array)
|
|
1085
1111
|
return self
|
|
1086
1112
|
|
|
1087
|
-
def __rmod__(self
|
|
1113
|
+
def __rmod__(self, other: Array | float, /) -> Array:
|
|
1088
1114
|
"""
|
|
1089
1115
|
Performs the operation __rmod__.
|
|
1090
1116
|
"""
|
|
1091
1117
|
other = self._check_allowed_dtypes(other, "real numeric", "__rmod__")
|
|
1092
1118
|
if other is NotImplemented:
|
|
1093
1119
|
return other
|
|
1094
|
-
self.
|
|
1120
|
+
self._check_type_device(other)
|
|
1095
1121
|
self, other = self._normalize_two_args(self, other)
|
|
1096
1122
|
res = self._array.__rmod__(other._array)
|
|
1097
1123
|
return self.__class__._new(res, device=self.device)
|
|
1098
1124
|
|
|
1099
|
-
def __imul__(self
|
|
1125
|
+
def __imul__(self, other: Array | complex, /) -> Array:
|
|
1100
1126
|
"""
|
|
1101
1127
|
Performs the operation __imul__.
|
|
1102
1128
|
"""
|
|
@@ -1106,19 +1132,19 @@ class Array:
|
|
|
1106
1132
|
self._array.__imul__(other._array)
|
|
1107
1133
|
return self
|
|
1108
1134
|
|
|
1109
|
-
def __rmul__(self
|
|
1135
|
+
def __rmul__(self, other: Array | complex, /) -> Array:
|
|
1110
1136
|
"""
|
|
1111
1137
|
Performs the operation __rmul__.
|
|
1112
1138
|
"""
|
|
1113
1139
|
other = self._check_allowed_dtypes(other, "numeric", "__rmul__")
|
|
1114
1140
|
if other is NotImplemented:
|
|
1115
1141
|
return other
|
|
1116
|
-
self.
|
|
1142
|
+
self._check_type_device(other)
|
|
1117
1143
|
self, other = self._normalize_two_args(self, other)
|
|
1118
1144
|
res = self._array.__rmul__(other._array)
|
|
1119
1145
|
return self.__class__._new(res, device=self.device)
|
|
1120
1146
|
|
|
1121
|
-
def __ior__(self
|
|
1147
|
+
def __ior__(self, other: Array | int, /) -> Array:
|
|
1122
1148
|
"""
|
|
1123
1149
|
Performs the operation __ior__.
|
|
1124
1150
|
"""
|
|
@@ -1128,11 +1154,11 @@ class Array:
|
|
|
1128
1154
|
self._array.__ior__(other._array)
|
|
1129
1155
|
return self
|
|
1130
1156
|
|
|
1131
|
-
def __ror__(self
|
|
1157
|
+
def __ror__(self, other: Array | int, /) -> Array:
|
|
1132
1158
|
"""
|
|
1133
1159
|
Performs the operation __ror__.
|
|
1134
1160
|
"""
|
|
1135
|
-
self.
|
|
1161
|
+
self._check_type_device(other)
|
|
1136
1162
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__ror__")
|
|
1137
1163
|
if other is NotImplemented:
|
|
1138
1164
|
return other
|
|
@@ -1140,7 +1166,7 @@ class Array:
|
|
|
1140
1166
|
res = self._array.__ror__(other._array)
|
|
1141
1167
|
return self.__class__._new(res, device=self.device)
|
|
1142
1168
|
|
|
1143
|
-
def __ipow__(self
|
|
1169
|
+
def __ipow__(self, other: Array | complex, /) -> Array:
|
|
1144
1170
|
"""
|
|
1145
1171
|
Performs the operation __ipow__.
|
|
1146
1172
|
"""
|
|
@@ -1150,11 +1176,11 @@ class Array:
|
|
|
1150
1176
|
self._array.__ipow__(other._array)
|
|
1151
1177
|
return self
|
|
1152
1178
|
|
|
1153
|
-
def __rpow__(self
|
|
1179
|
+
def __rpow__(self, other: Array | complex, /) -> Array:
|
|
1154
1180
|
"""
|
|
1155
1181
|
Performs the operation __rpow__.
|
|
1156
1182
|
"""
|
|
1157
|
-
from ._elementwise_functions import pow
|
|
1183
|
+
from ._elementwise_functions import pow # type: ignore[attr-defined]
|
|
1158
1184
|
|
|
1159
1185
|
other = self._check_allowed_dtypes(other, "numeric", "__rpow__")
|
|
1160
1186
|
if other is NotImplemented:
|
|
@@ -1163,7 +1189,7 @@ class Array:
|
|
|
1163
1189
|
# for 0-d arrays, so we use pow() here instead.
|
|
1164
1190
|
return pow(other, self)
|
|
1165
1191
|
|
|
1166
|
-
def __irshift__(self
|
|
1192
|
+
def __irshift__(self, other: Array | int, /) -> Array:
|
|
1167
1193
|
"""
|
|
1168
1194
|
Performs the operation __irshift__.
|
|
1169
1195
|
"""
|
|
@@ -1173,19 +1199,19 @@ class Array:
|
|
|
1173
1199
|
self._array.__irshift__(other._array)
|
|
1174
1200
|
return self
|
|
1175
1201
|
|
|
1176
|
-
def __rrshift__(self
|
|
1202
|
+
def __rrshift__(self, other: Array | int, /) -> Array:
|
|
1177
1203
|
"""
|
|
1178
1204
|
Performs the operation __rrshift__.
|
|
1179
1205
|
"""
|
|
1180
1206
|
other = self._check_allowed_dtypes(other, "integer", "__rrshift__")
|
|
1181
1207
|
if other is NotImplemented:
|
|
1182
1208
|
return other
|
|
1183
|
-
self.
|
|
1209
|
+
self._check_type_device(other)
|
|
1184
1210
|
self, other = self._normalize_two_args(self, other)
|
|
1185
1211
|
res = self._array.__rrshift__(other._array)
|
|
1186
1212
|
return self.__class__._new(res, device=self.device)
|
|
1187
1213
|
|
|
1188
|
-
def __isub__(self
|
|
1214
|
+
def __isub__(self, other: Array | complex, /) -> Array:
|
|
1189
1215
|
"""
|
|
1190
1216
|
Performs the operation __isub__.
|
|
1191
1217
|
"""
|
|
@@ -1195,19 +1221,19 @@ class Array:
|
|
|
1195
1221
|
self._array.__isub__(other._array)
|
|
1196
1222
|
return self
|
|
1197
1223
|
|
|
1198
|
-
def __rsub__(self
|
|
1224
|
+
def __rsub__(self, other: Array | complex, /) -> Array:
|
|
1199
1225
|
"""
|
|
1200
1226
|
Performs the operation __rsub__.
|
|
1201
1227
|
"""
|
|
1202
1228
|
other = self._check_allowed_dtypes(other, "numeric", "__rsub__")
|
|
1203
1229
|
if other is NotImplemented:
|
|
1204
1230
|
return other
|
|
1205
|
-
self.
|
|
1231
|
+
self._check_type_device(other)
|
|
1206
1232
|
self, other = self._normalize_two_args(self, other)
|
|
1207
1233
|
res = self._array.__rsub__(other._array)
|
|
1208
1234
|
return self.__class__._new(res, device=self.device)
|
|
1209
1235
|
|
|
1210
|
-
def __itruediv__(self
|
|
1236
|
+
def __itruediv__(self, other: Array | complex, /) -> Array:
|
|
1211
1237
|
"""
|
|
1212
1238
|
Performs the operation __itruediv__.
|
|
1213
1239
|
"""
|
|
@@ -1217,19 +1243,19 @@ class Array:
|
|
|
1217
1243
|
self._array.__itruediv__(other._array)
|
|
1218
1244
|
return self
|
|
1219
1245
|
|
|
1220
|
-
def __rtruediv__(self
|
|
1246
|
+
def __rtruediv__(self, other: Array | complex, /) -> Array:
|
|
1221
1247
|
"""
|
|
1222
1248
|
Performs the operation __rtruediv__.
|
|
1223
1249
|
"""
|
|
1224
1250
|
other = self._check_allowed_dtypes(other, "floating-point", "__rtruediv__")
|
|
1225
1251
|
if other is NotImplemented:
|
|
1226
1252
|
return other
|
|
1227
|
-
self.
|
|
1253
|
+
self._check_type_device(other)
|
|
1228
1254
|
self, other = self._normalize_two_args(self, other)
|
|
1229
1255
|
res = self._array.__rtruediv__(other._array)
|
|
1230
1256
|
return self.__class__._new(res, device=self.device)
|
|
1231
1257
|
|
|
1232
|
-
def __ixor__(self
|
|
1258
|
+
def __ixor__(self, other: Array | int, /) -> Array:
|
|
1233
1259
|
"""
|
|
1234
1260
|
Performs the operation __ixor__.
|
|
1235
1261
|
"""
|
|
@@ -1239,19 +1265,19 @@ class Array:
|
|
|
1239
1265
|
self._array.__ixor__(other._array)
|
|
1240
1266
|
return self
|
|
1241
1267
|
|
|
1242
|
-
def __rxor__(self
|
|
1268
|
+
def __rxor__(self, other: Array | int, /) -> Array:
|
|
1243
1269
|
"""
|
|
1244
1270
|
Performs the operation __rxor__.
|
|
1245
1271
|
"""
|
|
1246
1272
|
other = self._check_allowed_dtypes(other, "integer or boolean", "__rxor__")
|
|
1247
1273
|
if other is NotImplemented:
|
|
1248
1274
|
return other
|
|
1249
|
-
self.
|
|
1275
|
+
self._check_type_device(other)
|
|
1250
1276
|
self, other = self._normalize_two_args(self, other)
|
|
1251
1277
|
res = self._array.__rxor__(other._array)
|
|
1252
1278
|
return self.__class__._new(res, device=self.device)
|
|
1253
1279
|
|
|
1254
|
-
def to_device(self
|
|
1280
|
+
def to_device(self, device: Device, /, stream: None = None) -> Array:
|
|
1255
1281
|
if stream is not None:
|
|
1256
1282
|
raise ValueError("The stream argument to to_device() is not supported")
|
|
1257
1283
|
if device == self._device:
|
|
@@ -1262,7 +1288,7 @@ class Array:
|
|
|
1262
1288
|
raise ValueError(f"Unsupported device {device!r}")
|
|
1263
1289
|
|
|
1264
1290
|
@property
|
|
1265
|
-
def dtype(self) ->
|
|
1291
|
+
def dtype(self) -> DType:
|
|
1266
1292
|
"""
|
|
1267
1293
|
Array API compatible wrapper for :py:meth:`np.ndarray.dtype <numpy.ndarray.dtype>`.
|
|
1268
1294
|
|
|
@@ -1290,7 +1316,7 @@ class Array:
|
|
|
1290
1316
|
return self._array.ndim
|
|
1291
1317
|
|
|
1292
1318
|
@property
|
|
1293
|
-
def shape(self) ->
|
|
1319
|
+
def shape(self) -> tuple[int, ...]:
|
|
1294
1320
|
"""
|
|
1295
1321
|
Array API compatible wrapper for :py:meth:`np.ndarray.shape <numpy.ndarray.shape>`.
|
|
1296
1322
|
|