Skip to content

Commit aee3a56

Browse files
committed
Rename the array class in the array API namespace from ndarray to Array
The actual class name doesn't matter because it isn't part of the namespace API (arrays should be constructed with the array creation functions like asarray()). However, it is better to use a name that is different from the existing NumPy array object to avoid ambiguity.
1 parent fc1ff6f commit aee3a56

13 files changed

+192
-202
lines changed

numpy/_array_api/__init__.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
guaranteed to give a comprehensive coverage of the spec. Therefore, those
5959
reviewing this submodule should refer to the standard documents themselves.
6060
61-
- There is a custom array object, numpy._array_api.ndarray, which is returned
61+
- There is a custom array object, numpy._array_api.Array, which is returned
6262
by all functions in this module. All functions in the array API namespace
6363
implicitly assume that they will only receive this object as input. The only
6464
way to create instances of this object is to use one of the array creation
@@ -69,14 +69,14 @@
6969
limit/change certain behavior that differs in the spec. In particular:
7070
7171
- Indexing: Only a subset of indices supported by NumPy are required by the
72-
spec. The ndarray object restricts indexing to only allow those types of
72+
spec. The Array object restricts indexing to only allow those types of
7373
indices that are required by the spec. See the docstring of the
74-
numpy._array_api.ndarray._validate_indices helper function for more
74+
numpy._array_api.Array._validate_indices helper function for more
7575
information.
7676
7777
- Type promotion: Some type promotion rules are different in the spec. In
7878
particular, the spec does not have any value-based casting. Note that the
79-
code to correct the type promotion rules on numpy._array_api.ndarray is
79+
code to correct the type promotion rules on numpy._array_api.Array is
8080
not yet implemented.
8181
8282
- All functions include type annotations, corresponding to those given in the
@@ -93,7 +93,7 @@
9393
9494
Still TODO in this module are:
9595
96-
- Implement the spec type promotion rules on the ndarray object.
96+
- Implement the spec type promotion rules on the Array object.
9797
9898
- Disable NumPy warnings in the API functions.
9999

numpy/_array_api/_array_object.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222

2323
from typing import TYPE_CHECKING
2424
if TYPE_CHECKING:
25-
from ._types import Any, Optional, PyCapsule, Tuple, Union, Array
25+
from ._types import Any, Optional, PyCapsule, Tuple, Union, Device, Dtype
2626

2727
import numpy as np
2828

29-
class ndarray:
29+
class Array:
3030
"""
31-
ndarray object for the array API namespace.
31+
n-d array object for the array API namespace.
3232
3333
See the docstring of :py:obj:`np.ndarray <numpy.ndarray>` for more
3434
information.
@@ -46,7 +46,7 @@ class ndarray:
4646
@classmethod
4747
def _new(cls, x, /):
4848
"""
49-
This is a private method for initializing the array API ndarray
49+
This is a private method for initializing the array API Array
5050
object.
5151
5252
Functions outside of the array_api submodule should not use this
@@ -64,9 +64,9 @@ def _new(cls, x, /):
6464
obj._array = x
6565
return obj
6666

67-
# Prevent ndarray() from working
67+
# Prevent Array() from working
6868
def __new__(cls, *args, **kwargs):
69-
raise TypeError("The array_api ndarray object should not be instantiated directly. Use an array creation function, such as asarray(), instead.")
69+
raise TypeError("The array_api Array object should not be instantiated directly. Use an array creation function, such as asarray(), instead.")
7070

7171
# These functions are not required by the spec, but are implemented for
7272
# the sake of usability.
@@ -75,13 +75,13 @@ def __str__(self: Array, /) -> str:
7575
"""
7676
Performs the operation __str__.
7777
"""
78-
return self._array.__str__().replace('array', 'ndarray')
78+
return self._array.__str__().replace('array', 'Array')
7979

8080
def __repr__(self: Array, /) -> str:
8181
"""
8282
Performs the operation __repr__.
8383
"""
84-
return self._array.__repr__().replace('array', 'ndarray')
84+
return self._array.__repr__().replace('array', 'Array')
8585

8686
# Helper function to match the type promotion rules in the spec
8787
def _promote_scalar(self, scalar):
@@ -109,7 +109,7 @@ def _promote_scalar(self, scalar):
109109
# behavior for integers within the bounds of the integer dtype.
110110
# Outside of those bounds we use the default NumPy behavior (either
111111
# cast or raise OverflowError).
112-
return ndarray._new(np.array(scalar, self.dtype))
112+
return Array._new(np.array(scalar, self.dtype))
113113

114114
@staticmethod
115115
def _normalize_two_args(x1, x2):
@@ -135,9 +135,9 @@ def _normalize_two_args(x1, x2):
135135
# performant. broadcast_to(x1._array, x2.shape) is much slower. We
136136
# could also manually type promote x2, but that is more complicated
137137
# and about the same performance as this.
138-
x1 = ndarray._new(x1._array[None])
138+
x1 = Array._new(x1._array[None])
139139
elif x2.shape == () and x1.shape != ():
140-
x2 = ndarray._new(x2._array[None])
140+
x2 = Array._new(x2._array[None])
141141
return (x1, x2)
142142

143143
# Everything below this line is required by the spec.
@@ -284,7 +284,7 @@ def _validate_index(key, shape):
284284
Additionally, it should be noted that indices that would return a
285285
scalar in NumPy will return a shape () array. Array scalars are not allowed
286286
in the specification, only shape () arrays. This is done in the
287-
``ndarray._new`` constructor, not this function.
287+
``Array._new`` constructor, not this function.
288288
289289
"""
290290
if isinstance(key, slice):
@@ -313,7 +313,7 @@ def _validate_index(key, shape):
313313
return key
314314

315315
elif isinstance(key, tuple):
316-
key = tuple(ndarray._validate_index(idx, None) for idx in key)
316+
key = tuple(Array._validate_index(idx, None) for idx in key)
317317

318318
for idx in key:
319319
if isinstance(idx, np.ndarray) and idx.dtype in _boolean_dtypes or isinstance(idx, (bool, np.bool_)):
@@ -329,11 +329,11 @@ def _validate_index(key, shape):
329329
ellipsis_i = key.index(...) if n_ellipsis else len(key)
330330

331331
for idx, size in list(zip(key[:ellipsis_i], shape)) + list(zip(key[:ellipsis_i:-1], shape[:ellipsis_i:-1])):
332-
ndarray._validate_index(idx, (size,))
332+
Array._validate_index(idx, (size,))
333333
return key
334334
elif isinstance(key, bool):
335335
return key
336-
elif isinstance(key, ndarray):
336+
elif isinstance(key, Array):
337337
if key.dtype in _integer_dtypes:
338338
if key.shape != ():
339339
raise IndexError("Integer array indices with shape != () are not allowed in the array API namespace")
@@ -346,7 +346,7 @@ def _validate_index(key, shape):
346346
return operator.index(key)
347347
except TypeError:
348348
# Note: This also omits boolean arrays that are not already in
349-
# ndarray() form, like a list of booleans.
349+
# Array() form, like a list of booleans.
350350
raise IndexError("Only integers, slices (`:`), ellipsis (`...`), and boolean arrays are valid indices in the array API namespace")
351351

352352
def __getitem__(self: Array, key: Union[int, slice, ellipsis, Tuple[Union[int, slice, ellipsis], ...], Array], /) -> Array:

numpy/_array_api/_creation_functions.py

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ def asarray(obj: Union[float, NestedSequence[bool|int|float], SupportsDLPack, Su
1919
"""
2020
# _array_object imports in this file are inside the functions to avoid
2121
# circular imports
22-
from ._array_object import ndarray
22+
from ._array_object import Array
2323
if device is not None:
24-
# Note: Device support is not yet implemented on ndarray
24+
# Note: Device support is not yet implemented on Array
2525
raise NotImplementedError("Device support is not yet implemented")
2626
if copy is not None:
2727
# Note: copy is not yet implemented in np.asarray
2828
raise NotImplementedError("The copy keyword argument to asarray is not yet implemented")
29-
if isinstance(obj, ndarray) and (dtype is None or obj.dtype == dtype):
29+
if isinstance(obj, Array) and (dtype is None or obj.dtype == dtype):
3030
return obj
3131
if dtype is None and isinstance(obj, int) and (obj > 2**64 or obj < -2**63):
3232
# Give a better error message in this case. NumPy would convert this
@@ -35,58 +35,58 @@ def asarray(obj: Union[float, NestedSequence[bool|int|float], SupportsDLPack, Su
3535
res = np.asarray(obj, dtype=dtype)
3636
if res.dtype not in _all_dtypes:
3737
raise TypeError(f"The array_api namespace does not support the dtype '{res.dtype}'")
38-
return ndarray._new(res)
38+
return Array._new(res)
3939

4040
def arange(start: Union[int, float], /, stop: Optional[Union[int, float]] = None, step: Union[int, float] = 1, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
4141
"""
4242
Array API compatible wrapper for :py:func:`np.arange <numpy.arange>`.
4343
4444
See its docstring for more information.
4545
"""
46-
from ._array_object import ndarray
46+
from ._array_object import Array
4747
if device is not None:
48-
# Note: Device support is not yet implemented on ndarray
48+
# Note: Device support is not yet implemented on Array
4949
raise NotImplementedError("Device support is not yet implemented")
50-
return ndarray._new(np.arange(start, stop=stop, step=step, dtype=dtype))
50+
return Array._new(np.arange(start, stop=stop, step=step, dtype=dtype))
5151

5252
def empty(shape: Union[int, Tuple[int, ...]], *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
5353
"""
5454
Array API compatible wrapper for :py:func:`np.empty <numpy.empty>`.
5555
5656
See its docstring for more information.
5757
"""
58-
from ._array_object import ndarray
58+
from ._array_object import Array
5959
if device is not None:
60-
# Note: Device support is not yet implemented on ndarray
60+
# Note: Device support is not yet implemented on Array
6161
raise NotImplementedError("Device support is not yet implemented")
62-
return ndarray._new(np.empty(shape, dtype=dtype))
62+
return Array._new(np.empty(shape, dtype=dtype))
6363

6464
def empty_like(x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
6565
"""
6666
Array API compatible wrapper for :py:func:`np.empty_like <numpy.empty_like>`.
6767
6868
See its docstring for more information.
6969
"""
70-
from ._array_object import ndarray
70+
from ._array_object import Array
7171
if device is not None:
72-
# Note: Device support is not yet implemented on ndarray
72+
# Note: Device support is not yet implemented on Array
7373
raise NotImplementedError("Device support is not yet implemented")
74-
return ndarray._new(np.empty_like(x._array, dtype=dtype))
74+
return Array._new(np.empty_like(x._array, dtype=dtype))
7575

7676
def eye(n_rows: int, n_cols: Optional[int] = None, /, *, k: Optional[int] = 0, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
7777
"""
7878
Array API compatible wrapper for :py:func:`np.eye <numpy.eye>`.
7979
8080
See its docstring for more information.
8181
"""
82-
from ._array_object import ndarray
82+
from ._array_object import Array
8383
if device is not None:
84-
# Note: Device support is not yet implemented on ndarray
84+
# Note: Device support is not yet implemented on Array
8585
raise NotImplementedError("Device support is not yet implemented")
86-
return ndarray._new(np.eye(n_rows, M=n_cols, k=k, dtype=dtype))
86+
return Array._new(np.eye(n_rows, M=n_cols, k=k, dtype=dtype))
8787

8888
def from_dlpack(x: object, /) -> Array:
89-
# Note: dlpack support is not yet implemented on ndarray
89+
# Note: dlpack support is not yet implemented on Array
9090
raise NotImplementedError("DLPack support is not yet implemented")
9191

9292
def full(shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
@@ -95,101 +95,101 @@ def full(shape: Union[int, Tuple[int, ...]], fill_value: Union[int, float], *, d
9595
9696
See its docstring for more information.
9797
"""
98-
from ._array_object import ndarray
98+
from ._array_object import Array
9999
if device is not None:
100-
# Note: Device support is not yet implemented on ndarray
100+
# Note: Device support is not yet implemented on Array
101101
raise NotImplementedError("Device support is not yet implemented")
102-
if isinstance(fill_value, ndarray) and fill_value.ndim == 0:
103-
fill_value = fill_value._array[...]
102+
if isinstance(fill_value, Array) and fill_value.ndim == 0:
103+
fill_value = fill_value._array[...]
104104
res = np.full(shape, fill_value, dtype=dtype)
105105
if res.dtype not in _all_dtypes:
106106
# This will happen if the fill value is not something that NumPy
107107
# coerces to one of the acceptable dtypes.
108108
raise TypeError("Invalid input to full")
109-
return ndarray._new(res)
109+
return Array._new(res)
110110

111111
def full_like(x: Array, /, fill_value: Union[int, float], *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
112112
"""
113113
Array API compatible wrapper for :py:func:`np.full_like <numpy.full_like>`.
114114
115115
See its docstring for more information.
116116
"""
117-
from ._array_object import ndarray
117+
from ._array_object import Array
118118
if device is not None:
119-
# Note: Device support is not yet implemented on ndarray
119+
# Note: Device support is not yet implemented on Array
120120
raise NotImplementedError("Device support is not yet implemented")
121121
res = np.full_like(x._array, fill_value, dtype=dtype)
122122
if res.dtype not in _all_dtypes:
123123
# This will happen if the fill value is not something that NumPy
124124
# coerces to one of the acceptable dtypes.
125125
raise TypeError("Invalid input to full_like")
126-
return ndarray._new(res)
126+
return Array._new(res)
127127

128128
def linspace(start: Union[int, float], stop: Union[int, float], /, num: int, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None, endpoint: bool = True) -> Array:
129129
"""
130130
Array API compatible wrapper for :py:func:`np.linspace <numpy.linspace>`.
131131
132132
See its docstring for more information.
133133
"""
134-
from ._array_object import ndarray
134+
from ._array_object import Array
135135
if device is not None:
136-
# Note: Device support is not yet implemented on ndarray
136+
# Note: Device support is not yet implemented on Array
137137
raise NotImplementedError("Device support is not yet implemented")
138-
return ndarray._new(np.linspace(start, stop, num, dtype=dtype, endpoint=endpoint))
138+
return Array._new(np.linspace(start, stop, num, dtype=dtype, endpoint=endpoint))
139139

140140
def meshgrid(*arrays: Sequence[Array], indexing: str = 'xy') -> List[Array, ...]:
141141
"""
142142
Array API compatible wrapper for :py:func:`np.meshgrid <numpy.meshgrid>`.
143143
144144
See its docstring for more information.
145145
"""
146-
from ._array_object import ndarray
147-
return [ndarray._new(array) for array in np.meshgrid(*[a._array for a in arrays], indexing=indexing)]
146+
from ._array_object import Array
147+
return [Array._new(array) for array in np.meshgrid(*[a._array for a in arrays], indexing=indexing)]
148148

149149
def ones(shape: Union[int, Tuple[int, ...]], *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
150150
"""
151151
Array API compatible wrapper for :py:func:`np.ones <numpy.ones>`.
152152
153153
See its docstring for more information.
154154
"""
155-
from ._array_object import ndarray
155+
from ._array_object import Array
156156
if device is not None:
157-
# Note: Device support is not yet implemented on ndarray
157+
# Note: Device support is not yet implemented on Array
158158
raise NotImplementedError("Device support is not yet implemented")
159-
return ndarray._new(np.ones(shape, dtype=dtype))
159+
return Array._new(np.ones(shape, dtype=dtype))
160160

161161
def ones_like(x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
162162
"""
163163
Array API compatible wrapper for :py:func:`np.ones_like <numpy.ones_like>`.
164164
165165
See its docstring for more information.
166166
"""
167-
from ._array_object import ndarray
167+
from ._array_object import Array
168168
if device is not None:
169-
# Note: Device support is not yet implemented on ndarray
169+
# Note: Device support is not yet implemented on Array
170170
raise NotImplementedError("Device support is not yet implemented")
171-
return ndarray._new(np.ones_like(x._array, dtype=dtype))
171+
return Array._new(np.ones_like(x._array, dtype=dtype))
172172

173173
def zeros(shape: Union[int, Tuple[int, ...]], *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
174174
"""
175175
Array API compatible wrapper for :py:func:`np.zeros <numpy.zeros>`.
176176
177177
See its docstring for more information.
178178
"""
179-
from ._array_object import ndarray
179+
from ._array_object import Array
180180
if device is not None:
181-
# Note: Device support is not yet implemented on ndarray
181+
# Note: Device support is not yet implemented on Array
182182
raise NotImplementedError("Device support is not yet implemented")
183-
return ndarray._new(np.zeros(shape, dtype=dtype))
183+
return Array._new(np.zeros(shape, dtype=dtype))
184184

185185
def zeros_like(x: Array, /, *, dtype: Optional[Dtype] = None, device: Optional[Device] = None) -> Array:
186186
"""
187187
Array API compatible wrapper for :py:func:`np.zeros_like <numpy.zeros_like>`.
188188
189189
See its docstring for more information.
190190
"""
191-
from ._array_object import ndarray
191+
from ._array_object import Array
192192
if device is not None:
193-
# Note: Device support is not yet implemented on ndarray
193+
# Note: Device support is not yet implemented on Array
194194
raise NotImplementedError("Device support is not yet implemented")
195-
return ndarray._new(np.zeros_like(x._array, dtype=dtype))
195+
return Array._new(np.zeros_like(x._array, dtype=dtype))

0 commit comments

Comments
 (0)