77
88from pathlib import Path
99from types import ModuleType
10- from typing import Literal , Never , Protocol , TypeAlias
10+ from typing import Any , Literal , Never , Protocol , TypeAlias
1111from typing_extensions import TypeVar
1212
1313import optype as op
2727NS_co = TypeVar ("NS_co" , covariant = True , default = ModuleType )
2828Other_contra = TypeVar ("Other_contra" , contravariant = True , default = Never )
2929R_co = TypeVar ("R_co" , covariant = True , default = Never )
30+ DType_co = TypeVar ("DType_co" , covariant = True )
3031
3132
3233class HasArrayNamespace (Protocol [NS_co ]):
@@ -52,8 +53,20 @@ def __array_namespace__(
5253 ) -> NS_co : ...
5354
5455
56+ class HasDType (Protocol [DType_co ]):
57+ """Protocol for array classes that have a data type attribute."""
58+
59+ @property
60+ def dtype (self ) -> DType_co :
61+ """Data type of the array elements."""
62+ ...
63+
64+
5565@docstring_setter (** _array_docstrings )
5666class Array (
67+ # ------ Attributes -------
68+ HasDType [DType_co ],
69+ # ------ Methods -------
5770 HasArrayNamespace [NS_co ],
5871 op .CanPosSelf ,
5972 op .CanNegSelf ,
@@ -64,22 +77,23 @@ class Array(
6477 op .CanFloordivSame [Other_contra , R_co ],
6578 op .CanModSame [Other_contra , R_co ],
6679 op .CanPowSame [Other_contra , R_co ],
67- Protocol [Other_contra , R_co , NS_co ],
80+ Protocol [DType_co , Other_contra , R_co , NS_co ],
6881):
6982 """Array API specification for array object attributes and methods.
7083
71- The type is: ``Array[-Other = Never, +R = Never, +NS = ModuleType] =
72- Array[Self | Other, Self | R, NS]`` where:
84+ The type is: ``Array[+DType, -Other = Never, +R = Never, +NS = ModuleType] =
85+ Array[+DType, Self | Other, Self | R, NS]`` where:
7386
87+ - `DType` is the data type of the array elements.
7488 - `Other` is the type of objects that can be used with the array (e.g., for
7589 binary operations). For example, with numeric arrays, it is common to be
7690 able to add `float` and `int` objects to the array, not just other arrays
7791 of the same dtype. This would be annotated as `Other = float`. When not
7892 specified, `Other` only allows `Self` objects.
7993 - `R` is the return type of the array operations. For example, the return
8094 type of the division between integer arrays can be a float array. This
81- would be annotated as `R = float`. When not specified, `R` only allows
82- `Self` objects.
95+ would be annotated as `R = Array[ float] `. When not specified, `R` only
96+ allows `Self` objects.
8397 - `NS` is the type of the array namespace. It defaults to `ModuleType`,
8498 which is the most common form of array namespace (e.g., `numpy`, `cupy`,
8599 etc.). However, it can be any type, e.g. a `types.SimpleNamespace`, to
@@ -89,20 +103,47 @@ class Array(
89103 """
90104
91105
92- BoolArray : TypeAlias = Array [bool , Array [float , Never , NS_co ], NS_co ]
93- """Array API specification for boolean array object attributes and methods.
106+ # TODO: are there ways to tighten the dtype in both Arrays?
107+ BoolArray : TypeAlias = Array [DType_co , bool , Array [Any , float , Never , NS_co ], NS_co ]
108+ """Array API specification for arrays that work with boolean values.
94109
95- Specifically, this type alias fills the `Other_contra` type variable with
96- `bool`, allowing for `bool` objects to be added, subtracted, multiplied, etc. to
97- the array object.
110+ The type is: ``BoolArray[+DType, +NS = ModuleType] = Array[+DType, Self | bool,
111+ Self | Array[Any, float, Self, NS], Self, NS]`` where:
98112
99- """
113+ - `DType` is the data type of the array elements.
114+ - The second type variable -- `Other` -- is filled with `bool`, allowing for
115+ `bool` objects to be added, subtracted, multiplied, etc. to the array object.
116+ - The third type variable -- `R` -- is filled with `Array[Any, float, Self,
117+ NS]`, which is the return type of the array operations. For example, the
118+ return type of the division between boolean arrays can be a float array.
119+ - `NS` is the type of the array namespace. It defaults to `ModuleType`, which is
120+ the most common form of array namespace (e.g., `numpy`, `cupy`, etc.).
121+ However, it can be any type, e.g. a `types.SimpleNamespace`, to allow for
122+ wrapper libraries to semi-dynamically define their own array namespaces based
123+ on the wrapped array type.
100124
101- NumericArray : TypeAlias = Array [float | int , NS_co ]
102- """Array API specification for numeric array object attributes and methods.
125+ """
103126
104- Specifically, this type alias fills the `Other_contra` type variable with `float
105- | int`, allowing for `float | int` objects to be added, subtracted, multiplied,
106- etc. to the array object.
127+ # TODO: are there ways to tighten the dtype in both Arrays?
128+ NumericArray : TypeAlias = Array [
129+ DType_co , float | int , Array [Any , float | int , Never , NS_co ], NS_co
130+ ]
131+ """Array API specification for arrays that work with numeric values.
132+
133+ the type is: ``NumericArray[+DType, +NS = ModuleType] = Array[+DType, Self |
134+ float | int, Self | Array[Any, float | int, Self, NS], NS]`` where:
135+
136+ - `DType` is the data type of the array elements.
137+ - The second type variable -- `Other` -- is filled with `float | int`, allowing
138+ for `float | int` objects to be added, subtracted, multiplied, etc. to the
139+ array object.
140+ - The third type variable -- `R` -- is filled with `Array[Any, float | int,
141+ Self, NS]`, which is the return type of the array operations. For example, the
142+ return type of the division between integer arrays can be a float array.
143+ - `NS` is the type of the array namespace. It defaults to `ModuleType`, which is
144+ the most common form of array namespace (e.g., `numpy`, `cupy`, etc.).
145+ However, it can be any type, e.g. a `types.SimpleNamespace`, to allow for
146+ wrapper libraries to semi-dynamically define their own array namespaces based
147+ on the wrapped array type.
107148
108149"""
0 commit comments