Description
https://data-apis.org/array-api/latest/API_specification/index.html
goal
The goal is to provide Protocols
that can be used to type e.g. scipy.fft.fftfreq
(through its xp
kwarg) and scipy.fft.fftshift
(via the passed array).
the (big) problems
- The dtype spec only defines
__eq__
, which also exists inobject
. So it's impossible to (structurally) type a "dtype". - In the same way, it's impossible to (structurally) type a "device".
- Shapes are defined as tuples of "something". So the best we can do is type the number of dimensions, and ignore the axis types.
This means that static type-checkers won't be able to see the difference between a boolean array on your CPU, and a complex-floating array on a quantum computer within the core of a neutron star in the Andromeda galaxy.
so now what?
We can still figure out the following types:
Array
+ the dimensionality (becauseshape: tuple[?, ...]
kinda tells us thendim
, but not the actual shape)Namespace
, which is a protocollable module-type (often namedxp
), that could give usxp.array
: the specificArray
type (but there's still no HKT after asking for it for over 6 years...), andxp.(bool|((u?)int|float|complex)(8|16|32|64))
-i.e. the impossible-to-typeDType
types (🎩 🪄 🐰)xp.__array_namespace_info__() -> Info
(docs), an object with some other "magical" methods:.default_device() -> DefaultDevice
.devices() -> list[Device]
.dtypes(*, device: Device?, kind: Kind?)
- withKind
a literal string category, which allows us to "categorize" the e.g. floats, ints, and complexes (assuming the lib properly typed it), i.e. as type aliases.
problem solved: just type the untypeable
Note that we can also obtain the Info
type via Array
, since Array.__array_namespace__() -> Namespace[Info]
s.t. Namespace[InfoT].__array_namespace_info__() -> InfoT
(ignoring the versions).
So we can get all dtype types from either Array
or Namespace
, and we can either one from the other, and vice-versa (i.e. bidirectionally in both ways, and also the other way around).