11
11
NestedSequence ,
12
12
SupportsBufferProtocol ,
13
13
)
14
- from collections .abc import Sequence
15
14
from ._dtypes import _DType , _all_dtypes
16
15
17
16
import numpy as np
@@ -22,6 +21,12 @@ def _check_valid_dtype(dtype):
22
21
if dtype not in (None ,) + _all_dtypes :
23
22
raise ValueError ("dtype must be one of the supported dtypes" )
24
23
24
+ def _supports_buffer_protocol (obj ):
25
+ try :
26
+ memoryview (obj )
27
+ except TypeError :
28
+ return False
29
+ return True
25
30
26
31
def asarray (
27
32
obj : Union [
@@ -36,7 +41,7 @@ def asarray(
36
41
* ,
37
42
dtype : Optional [Dtype ] = None ,
38
43
device : Optional [Device ] = None ,
39
- copy : Optional [Union [ bool , np . _CopyMode ] ] = None ,
44
+ copy : Optional [bool ] = None ,
40
45
) -> Array :
41
46
"""
42
47
Array API compatible wrapper for :py:func:`np.asarray <numpy.asarray>`.
@@ -53,20 +58,37 @@ def asarray(
53
58
_np_dtype = dtype ._np_dtype
54
59
if device not in [CPU_DEVICE , None ]:
55
60
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
+
59
85
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 ))
65
87
if dtype is None and isinstance (obj , int ) and (obj > 2 ** 64 or obj < - (2 ** 63 )):
66
88
# Give a better error message in this case. NumPy would convert this
67
89
# to an object array. TODO: This won't handle large integers in lists.
68
90
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 )
70
92
return Array ._new (res )
71
93
72
94
0 commit comments