1111 NestedSequence ,
1212 SupportsBufferProtocol ,
1313 )
14- from collections .abc import Sequence
1514from ._dtypes import _DType , _all_dtypes
1615
1716import numpy as np
@@ -22,6 +21,12 @@ def _check_valid_dtype(dtype):
2221 if dtype not in (None ,) + _all_dtypes :
2322 raise ValueError ("dtype must be one of the supported dtypes" )
2423
24+ def _supports_buffer_protocol (obj ):
25+ try :
26+ memoryview (obj )
27+ except TypeError :
28+ return False
29+ return True
2530
2631def asarray (
2732 obj : Union [
@@ -36,7 +41,7 @@ def asarray(
3641 * ,
3742 dtype : Optional [Dtype ] = None ,
3843 device : Optional [Device ] = None ,
39- copy : Optional [Union [ bool , np . _CopyMode ] ] = None ,
44+ copy : Optional [bool ] = None ,
4045) -> Array :
4146 """
4247 Array API compatible wrapper for :py:func:`np.asarray <numpy.asarray>`.
@@ -53,20 +58,37 @@ def asarray(
5358 _np_dtype = dtype ._np_dtype
5459 if device not in [CPU_DEVICE , None ]:
5560 raise ValueError (f"Unsupported device { device !r} " )
56- if copy in (False , np ._CopyMode .IF_NEEDED ):
57- # Note: copy=False is not yet implemented in np.asarray
58- raise NotImplementedError ("copy=False is not yet implemented" )
61+
62+ if np .__version__ [0 ] < '2' :
63+ if copy is False :
64+ # Note: copy=False is not yet implemented in np.asarray for
65+ # NumPy 1
66+
67+ # Work around it by creating the new array and seeing if NumPy
68+ # copies it.
69+ if isinstance (obj , Array ):
70+ new_array = np .array (obj ._array , copy = copy , dtype = _np_dtype )
71+ if new_array is not obj ._array :
72+ raise ValueError ("Unable to avoid copy while creating an array from given array." )
73+ return Array ._new (new_array )
74+ elif _supports_buffer_protocol (obj ):
75+ # Buffer protocol will always support no-copy
76+ return Array ._new (np .array (obj , copy = copy , dtype = _np_dtype ))
77+ else :
78+ # No-copy is unsupported for Python built-in types.
79+ raise ValueError ("Unable to avoid copy while creating an array from given object." )
80+
81+ if copy is None :
82+ # NumPy 1 treats copy=False the same as the standard copy=None
83+ copy = False
84+
5985 if isinstance (obj , Array ):
60- if dtype is not None and obj .dtype != dtype :
61- copy = True
62- if copy in (True , np ._CopyMode .ALWAYS ):
63- return Array ._new (np .array (obj ._array , copy = True , dtype = _np_dtype ))
64- return obj
86+ return Array ._new (np .array (obj ._array , copy = copy , dtype = _np_dtype ))
6587 if dtype is None and isinstance (obj , int ) and (obj > 2 ** 64 or obj < - (2 ** 63 )):
6688 # Give a better error message in this case. NumPy would convert this
6789 # to an object array. TODO: This won't handle large integers in lists.
6890 raise OverflowError ("Integer out of bounds for array dtypes" )
69- res = np .asarray (obj , dtype = _np_dtype )
91+ res = np .array (obj , dtype = _np_dtype , copy = copy )
7092 return Array ._new (res )
7193
7294
0 commit comments