@@ -67,9 +67,7 @@ def __hash__(self) -> int:
67
67
CPU_DEVICE = Device ()
68
68
ALL_DEVICES = (CPU_DEVICE , Device ("device1" ), Device ("device2" ))
69
69
70
- # See https://github.com/data-apis/array-api-strict/issues/67 and the comment
71
- # on __array__ below.
72
- _allow_array = True
70
+ _default = object ()
73
71
74
72
75
73
class Array :
@@ -151,40 +149,28 @@ def __repr__(self) -> str:
151
149
152
150
__str__ = __repr__
153
151
154
- # In the future, _allow_array will be set to False, which will disallow
155
- # __array__. This means calling `np.func()` on an array_api_strict array
156
- # will give an error. If we don't explicitly disallow it, NumPy defaults
157
- # to creating an object dtype array, which would lead to confusing error
158
- # messages at best and surprising bugs at worst. The reason for doing this
159
- # is that __array__ is not actually supported by the standard, so it can
160
- # lead to code assuming np.asarray(other_array) would always work in the
161
- # standard.
162
- #
163
- # This was implemented historically for compatibility, and removing it has
152
+ # `__array__` was implemented historically for compatibility, and removing it has
164
153
# caused issues for some libraries (see
165
154
# https://github.com/data-apis/array-api-strict/issues/67).
166
- def __array__ (
167
- self , dtype : None | np .dtype [Any ] = None , copy : None | bool = None
168
- ) -> npt .NDArray [Any ]:
169
- # We have to allow this to be internally enabled as there's no other
170
- # easy way to parse a list of Array objects in asarray().
171
- if _allow_array :
172
- if self ._device != CPU_DEVICE :
173
- raise RuntimeError (f"Can not convert array on the '{ self ._device } ' device to a Numpy array." )
174
- # copy keyword is new in 2.0.0; for older versions don't use it
175
- # retry without that keyword.
176
- if np .__version__ [0 ] < '2' :
177
- return np .asarray (self ._array , dtype = dtype )
178
- elif np .__version__ .startswith ('2.0.0-dev0' ):
179
- # Handle dev version for which we can't know based on version
180
- # number whether or not the copy keyword is supported.
181
- try :
182
- return np .asarray (self ._array , dtype = dtype , copy = copy )
183
- except TypeError :
184
- return np .asarray (self ._array , dtype = dtype )
185
- else :
186
- return np .asarray (self ._array , dtype = dtype , copy = copy )
187
- 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
+ )
188
174
189
175
# These are various helper functions to make the array behavior match the
190
176
# spec in places where it either deviates from or is more strict than
0 commit comments