Skip to content

Commit 96adf91

Browse files
committed
✨ add CanArray* unop and binop protocols
Signed-off-by: Nathaniel Starkman <nstarman@users.noreply.github.com> WIP Signed-off-by: Nathaniel Starkman <nstarman@users.noreply.github.com>
1 parent 858a3db commit 96adf91

8 files changed

Lines changed: 478 additions & 12 deletions

File tree

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dependencies = [
2929
"typing-extensions>=4.14.1",
3030
"optype>=0.9.3; python_version < '3.11'",
3131
"optype>=0.12.2; python_version >= '3.11'",
32+
"tomli>=1.2.0 ; python_full_version < '3.11'",
3233
]
3334

3435
[project.urls]
@@ -123,9 +124,12 @@ ignore = [
123124
"D107", # Missing docstring in __init__
124125
"D203", # 1 blank line required before class docstring
125126
"D213", # Multi-line docstring summary should start at the second line
127+
"D401", # First line of docstring should be in imperative mood
126128
"FBT", # flake8-boolean-trap
127129
"FIX", # flake8-fixme
128130
"ISC001", # Conflicts with formatter
131+
"PLW1641", # Object does not implement `__hash__` method
132+
"PYI041", # Use `float` instead of `int | float`
129133
]
130134

131135
[tool.ruff.lint.pylint]

src/array_api_typing/_array.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
__all__ = (
22
"Array",
3+
"BoolArray",
34
"HasArrayNamespace",
5+
"NumericArray",
46
)
57

8+
from pathlib import Path
69
from types import ModuleType
7-
from typing import Literal, Protocol
10+
from typing import Literal, Never, Protocol, TypeAlias
811
from typing_extensions import TypeVar
912

13+
import optype as op
14+
15+
from ._utils import docstring_setter
16+
17+
# Load docstrings from TOML file
18+
try:
19+
import tomllib
20+
except ImportError:
21+
import tomli as tomllib # type: ignore[import-not-found, no-redef]
22+
23+
_docstrings_path = Path(__file__).parent / "_array_docstrings.toml"
24+
with _docstrings_path.open("rb") as f:
25+
_array_docstrings = tomllib.load(f)["docstrings"]
26+
1027
NS_co = TypeVar("NS_co", covariant=True, default=ModuleType)
28+
T_contra = TypeVar("T_contra", contravariant=True)
29+
R_co = TypeVar("R_co", covariant=True, default=Never)
1130

1231

1332
class HasArrayNamespace(Protocol[NS_co]):
@@ -33,8 +52,37 @@ def __array_namespace__(
3352
) -> NS_co: ...
3453

3554

55+
@docstring_setter(**_array_docstrings)
3656
class Array(
3757
HasArrayNamespace[NS_co],
38-
Protocol[NS_co],
58+
op.CanPosSelf,
59+
op.CanNegSelf,
60+
op.CanAddSame[T_contra, R_co],
61+
op.CanSubSame[T_contra, R_co],
62+
op.CanMulSame[T_contra, R_co],
63+
op.CanTruedivSame[T_contra, R_co],
64+
op.CanFloordivSame[T_contra, R_co],
65+
op.CanModSame[T_contra, R_co],
66+
op.CanPowSame[T_contra, R_co],
67+
Protocol[T_contra, R_co, NS_co],
3968
):
4069
"""Array API specification for array object attributes and methods."""
70+
71+
72+
BoolArray: TypeAlias = Array[bool, Array[float, Never, NS_co], NS_co]
73+
"""Array API specification for boolean array object attributes and methods.
74+
75+
Specifically, this type alias fills the `T_contra` type variable with
76+
`bool`, allowing for `bool` objects to be added, subtracted, multiplied, etc. to
77+
the array object.
78+
79+
"""
80+
81+
NumericArray: TypeAlias = Array[float | int, NS_co]
82+
"""Array API specification for numeric array object attributes and methods.
83+
84+
Specifically, this type alias fills the `T_contra` type variable with `float
85+
| int`, allowing for `float | int` objects to be added, subtracted, multiplied,
86+
etc. to the array object.
87+
88+
"""
Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
[docstrings]
2+
__pos__ = '''
3+
Evaluates `+self_i` for each element of an array instance.
4+
5+
Returns:
6+
Self: An array containing the evaluated result for each element.
7+
The returned array must have the same data type as `self`.
8+
9+
See Also:
10+
array_api_typing.Positive
11+
12+
'''
13+
14+
__neg__ = '''
15+
Evaluates `-self_i` for each element of an array instance.
16+
17+
Returns:
18+
Self: an array containing the evaluated result for each element in
19+
`self`. The returned array must have a data type determined by Type
20+
Promotion Rules.
21+
22+
See Also:
23+
array_api_typing.Negative
24+
25+
'''
26+
27+
__add__ = '''
28+
Calculates the sum for each element of an array instance with the respective
29+
element of the array `other`.
30+
31+
Args:
32+
other: addend array. Must be compatible with `self` (see
33+
Broadcasting). Should have a numeric data type.
34+
35+
Returns:
36+
Self: an array containing the element-wise sums. The returned array
37+
must have a data type determined by Type Promotion Rules.
38+
39+
See Also:
40+
array_api_typing.Add
41+
42+
'''
43+
44+
__radd__ = '''
45+
Calculates the sum for each element of the array `other` with the respective
46+
element of an array instance.
47+
48+
Args:
49+
other: addend array. Must be compatible with `self` (see Broadcasting).
50+
Should have a numeric data type.
51+
52+
Returns:
53+
Self: an array containing the element-wise sums. The returned array
54+
must have a data type determined by Type Promotion Rules.
55+
56+
See Also:
57+
array_api_typing.Add
58+
59+
'''
60+
61+
__sub__ = '''
62+
Calculates the difference for each element of an array instance with the
63+
respective element of the array other.
64+
65+
The result of `self_i - other_i` must be the same as `self_i +
66+
(-other_i)` and must be governed by the same floating-point rules as
67+
addition (see `CanArrayAdd`).
68+
69+
Args:
70+
other: subtrahend array. Must be compatible with `self` (see
71+
Broadcasting). Should have a numeric data type.
72+
73+
Returns:
74+
Self: an array containing the element-wise differences. The returned
75+
array must have a data type determined by Type Promotion Rules.
76+
77+
See Also:
78+
array_api_typing.Subtract
79+
80+
'''
81+
82+
__rsub__ = '''
83+
Calculates the difference for each element of the array `other` with the
84+
respective element of an array instance.
85+
86+
The result of `other_i - self_i` must be the same as `other_i + (-self_i)`
87+
and must be governed by the same floating-point rules as addition (see
88+
`CanArrayAdd`).
89+
90+
Args:
91+
other: minuend array. Must be compatible with `self` (see Broadcasting).
92+
Should have a numeric data type.
93+
94+
Returns:
95+
Self: an array containing the element-wise differences. The returned
96+
array must have a data type determined by Type Promotion Rules.
97+
98+
See Also:
99+
array_api_typing.Subtract
100+
101+
'''
102+
103+
__mul__ = '''
104+
Calculates the product for each element of an array instance with the
105+
respective element of the array `other`.
106+
107+
Args:
108+
other: multiplicand array. Must be compatible with `self` (see
109+
Broadcasting). Should have a numeric data type.
110+
111+
Returns:
112+
Self: an array containing the element-wise products. The returned
113+
array must have a data type determined by Type Promotion Rules.
114+
115+
See Also:
116+
array_api_typing.Multiply
117+
118+
'''
119+
120+
__rmul__ = '''
121+
Calculates the product for each element of the array `other` with the
122+
respective element of an array instance.
123+
124+
Args:
125+
other: multiplicand array. Must be compatible with `self` (see
126+
Broadcasting). Should have a numeric data type.
127+
128+
Returns:
129+
Self: an array containing the element-wise products. The returned array
130+
must have a data type determined by Type Promotion Rules.
131+
132+
See Also:
133+
array_api_typing.Multiply
134+
135+
'''
136+
137+
__truediv__ = '''
138+
Evaluates `self_i / other_i` for each element of an array instance with the
139+
respective element of the array `other`.
140+
141+
Args:
142+
other: Must be compatible with `self` (see Broadcasting). Should have a
143+
numeric data type.
144+
145+
Returns:
146+
Self: an array containing the element-wise results. The returned array
147+
should have a floating-point data type determined by Type Promotion
148+
Rules.
149+
150+
See Also:
151+
array_api_typing.TrueDiv
152+
153+
'''
154+
155+
__rtruediv__ = '''
156+
Calculates the quotient for each element of the array `other` with the
157+
respective element of an array instance.
158+
159+
Args:
160+
other: dividend array. Must be compatible with `self` (see Broadcasting).
161+
Should have a numeric data type.
162+
163+
Returns:
164+
Self: an array containing the element-wise quotients. The returned
165+
array must have a data type determined by Type Promotion Rules.
166+
167+
See Also:
168+
array_api_typing.TrueDiv
169+
170+
'''
171+
172+
__floordiv__ = '''
173+
Evaluates `self_i // other_i` for each element of an array instance with the
174+
respective element of the array `other`.
175+
176+
Args:
177+
other: Must be compatible with `self` (see Broadcasting). Should have a
178+
numeric data type.
179+
180+
Returns:
181+
Self: an array containing the element-wise results. The returned array
182+
must have a data type determined by Type Promotion Rules.
183+
184+
See Also:
185+
array_api_typing.FloorDiv
186+
187+
'''
188+
189+
__rfloordiv__ = '''
190+
Calculates the floor division for each element of the array `other` with the
191+
respective element of an array instance.
192+
193+
Args:
194+
other: dividend array. Must be compatible with `self` (see Broadcasting).
195+
Should have a numeric data type.
196+
197+
Returns:
198+
Self: an array containing the element-wise floor division results. The
199+
returned array must have a data type determined by Type Promotion
200+
Rules.
201+
202+
See Also:
203+
array_api_typing.FloorDiv
204+
205+
'''
206+
207+
__mod__ = '''
208+
Evaluates `self_i % other_i` for each element of an array instance with the
209+
respective element of the array `other`.
210+
211+
Args:
212+
other: Must be compatible with `self` (see Broadcasting). Should have a
213+
numeric data type.
214+
215+
Returns:
216+
Self: an array containing the element-wise results. Each element-wise
217+
result must have the same sign as the respective element `other_i`.
218+
The returned array must have a floating-point data type determined
219+
by Type Promotion Rules.
220+
221+
See Also:
222+
array_api_typing.Remainder
223+
224+
'''
225+
226+
__rmod__ = '''
227+
Calculates the remainder for each element of the array `other` with the
228+
respective element of an array instance.
229+
230+
Args:
231+
other: dividend array. Must be compatible with `self` (see Broadcasting).
232+
Should have a numeric data type.
233+
234+
Returns:
235+
Self: an array containing the element-wise remainders. The returned
236+
array must have a data type determined by Type Promotion Rules.
237+
238+
See Also:
239+
array_api_typing.Remainder
240+
241+
'''
242+
243+
__pow__ = '''
244+
Calculates an implementation-dependent approximation of exponentiation by
245+
raising each element (the base) of an array instance to the power of
246+
`other_i` (the exponent), where `other_i` is the corresponding element of
247+
the array `other`.
248+
249+
Args:
250+
other: array whose elements correspond to the exponentiation exponent.
251+
Must be compatible with `self` (see Broadcasting). Should have a
252+
numeric data type.
253+
254+
Returns:
255+
Self: an array containing the element-wise results. The returned array
256+
must have a data type determined by Type Promotion Rules.
257+
258+
'''
259+
260+
__rpow__ = '''
261+
Calculates the power for each element of the array `other` raised to the
262+
respective element of an array instance.
263+
264+
Args:
265+
other: base array. Must be compatible with `self` (see Broadcasting).
266+
Should have a numeric data type.
267+
268+
Returns:
269+
Self: an array containing the element-wise powers. The returned array
270+
must have a data type determined by Type Promotion Rules.
271+
272+
See Also:
273+
array_api_typing.Power
274+
275+
'''

src/array_api_typing/_namespace.py

Whitespace-only changes.

0 commit comments

Comments
 (0)