1
1
# flake8: noqa
2
+ import functools
2
3
import sys
3
4
import codecs
4
5
import array
5
6
from functools import reduce
6
7
7
8
import numpy as np
8
9
10
+ from .ndarray_like import NDArrayLike , is_ndarray_like
9
11
10
- def ensure_ndarray ( buf ):
11
- """Convenience function to coerce ` buf` to a numpy array, if it is not already a
12
- numpy array.
12
+
13
+ def ensure_ndarray_like ( buf ) -> NDArrayLike :
14
+ """Convenience function to coerce `buf` to ndarray-like array.
13
15
14
16
Parameters
15
17
----------
16
- buf : array-like or bytes-like
17
- A numpy array or any object exporting a buffer interface.
18
+ buf : ndarray-like, array-like, or bytes-like
19
+ A numpy array like object such as numpy.ndarray, cupy.ndarray, or
20
+ any object exporting a buffer interface.
18
21
19
22
Returns
20
23
-------
21
- arr : ndarray
22
- A numpy array , sharing memory with `buf`.
24
+ arr : NDArrayLike
25
+ A ndarray-like , sharing memory with `buf`.
23
26
24
27
Notes
25
28
-----
26
29
This function will not create a copy under any circumstances, it is guaranteed to
27
30
return a view on memory exported by `buf`.
28
-
29
31
"""
30
32
31
- if isinstance (buf , np .ndarray ):
32
- # already a numpy array
33
- arr = buf
33
+ if not is_ndarray_like (buf ):
34
+ if isinstance (buf , array .array ) and buf .typecode in "cu" :
35
+ # Guard condition, do not support array.array with unicode type, this is
36
+ # problematic because numpy does not support it on all platforms. Also do not
37
+ # support char as it was removed in Python 3.
38
+ raise TypeError ("array.array with char or unicode type is not supported" )
39
+ else :
40
+ # N.B., first take a memoryview to make sure that we subsequently create a
41
+ # numpy array from a memory buffer with no copy
42
+ mem = memoryview (buf )
43
+ # instantiate array from memoryview, ensures no copy
44
+ buf = np .array (mem , copy = False )
45
+ return buf
34
46
35
- elif isinstance (buf , array .array ) and buf .typecode in 'cu' :
36
- # Guard condition, do not support array.array with unicode type, this is
37
- # problematic because numpy does not support it on all platforms. Also do not
38
- # support char as it was removed in Python 3.
39
- raise TypeError ('array.array with char or unicode type is not supported' )
40
47
41
- else :
48
+ def ensure_ndarray (buf ) -> np .ndarray :
49
+ """Convenience function to coerce `buf` to a numpy array, if it is not already a
50
+ numpy array.
42
51
43
- # N.B., first take a memoryview to make sure that we subsequently create a
44
- # numpy array from a memory buffer with no copy
45
- mem = memoryview (buf )
52
+ Parameters
53
+ ----------
54
+ buf : array-like or bytes-like
55
+ A numpy array or any object exporting a buffer interface.
46
56
47
- # instantiate array from memoryview, ensures no copy
48
- arr = np .array (mem , copy = False )
57
+ Returns
58
+ -------
59
+ arr : ndarray
60
+ A numpy array, sharing memory with `buf`.
49
61
50
- return arr
62
+ Notes
63
+ -----
64
+ This function will not create a copy under any circumstances, it is guaranteed to
65
+ return a view on memory exported by `buf`.
66
+ """
67
+ return np .array (ensure_ndarray_like (buf ), copy = False )
51
68
52
69
53
- def ensure_contiguous_ndarray (buf , max_buffer_size = None , flatten = True ):
54
- """Convenience function to coerce `buf` to a numpy array, if it is not already a
55
- numpy array. Also ensures that the returned value exports fully contiguous memory,
70
+ def ensure_contiguous_ndarray_like (
71
+ buf , max_buffer_size = None , flatten = True
72
+ ) -> NDArrayLike :
73
+ """Convenience function to coerce `buf` to ndarray-like array.
74
+ Also ensures that the returned value exports fully contiguous memory,
56
75
and supports the new-style buffer interface. If the optional max_buffer_size is
57
76
provided, raise a ValueError if the number of bytes consumed by the returned
58
77
array exceeds this value.
59
78
60
79
Parameters
61
80
----------
62
- buf : array-like or bytes-like
63
- A numpy array or any object exporting a buffer interface.
81
+ buf : ndarray-like, array-like, or bytes-like
82
+ A numpy array like object such as numpy.ndarray, cupy.ndarray, or
83
+ any object exporting a buffer interface.
64
84
max_buffer_size : int
65
85
If specified, the largest allowable value of arr.nbytes, where arr
66
86
is the returned array.
87
+ flatten : bool
88
+ If True, the array are flatten.
67
89
68
90
Returns
69
91
-------
70
- arr : ndarray
71
- A numpy array , sharing memory with `buf`.
92
+ arr : NDArrayLike
93
+ A ndarray-like , sharing memory with `buf`.
72
94
73
95
Notes
74
96
-----
75
97
This function will not create a copy under any circumstances, it is guaranteed to
76
98
return a view on memory exported by `buf`.
77
-
78
99
"""
79
-
80
- # ensure input is a numpy array
81
- arr = ensure_ndarray (buf )
100
+ arr = ensure_ndarray_like (buf )
82
101
83
102
# check for object arrays, these are just memory pointers, actual memory holding
84
103
# item data is scattered elsewhere
85
104
if arr .dtype == object :
86
- raise TypeError (' object arrays are not supported' )
105
+ raise TypeError (" object arrays are not supported" )
87
106
88
107
# check for datetime or timedelta ndarray, the buffer interface doesn't support those
89
- if arr .dtype .kind in 'Mm' :
108
+ if arr .dtype .kind in "Mm" :
90
109
arr = arr .view (np .int64 )
91
110
92
111
# check memory is contiguous, if so flatten
93
112
if arr .flags .c_contiguous or arr .flags .f_contiguous :
94
- # check if flatten flag is on or not
95
113
if flatten :
96
114
# can flatten without copy
97
- arr = arr .reshape (- 1 , order = 'A' )
98
-
115
+ arr = arr .reshape (- 1 , order = "A" )
99
116
else :
100
- raise ValueError (' an array with contiguous memory is required' )
117
+ raise ValueError (" an array with contiguous memory is required" )
101
118
102
119
if max_buffer_size is not None and arr .nbytes > max_buffer_size :
103
120
msg = "Codec does not support buffers of > {} bytes" .format (max_buffer_size )
@@ -106,45 +123,78 @@ def ensure_contiguous_ndarray(buf, max_buffer_size=None, flatten=True):
106
123
return arr
107
124
108
125
109
- def ensure_bytes (buf ):
126
+ def ensure_contiguous_ndarray (buf , max_buffer_size = None , flatten = True ) -> np .array :
127
+ """Convenience function to coerce `buf` to a numpy array, if it is not already a
128
+ numpy array. Also ensures that the returned value exports fully contiguous memory,
129
+ and supports the new-style buffer interface. If the optional max_buffer_size is
130
+ provided, raise a ValueError if the number of bytes consumed by the returned
131
+ array exceeds this value.
132
+
133
+ Parameters
134
+ ----------
135
+ buf : array-like or bytes-like
136
+ A numpy array or any object exporting a buffer interface.
137
+ max_buffer_size : int
138
+ If specified, the largest allowable value of arr.nbytes, where arr
139
+ is the returned array.
140
+ flatten : bool
141
+ If True, the array are flatten.
142
+
143
+ Returns
144
+ -------
145
+ arr : ndarray
146
+ A numpy array, sharing memory with `buf`.
147
+
148
+ Notes
149
+ -----
150
+ This function will not create a copy under any circumstances, it is guaranteed to
151
+ return a view on memory exported by `buf`.
152
+ """
153
+
154
+ return ensure_ndarray (
155
+ ensure_contiguous_ndarray_like (
156
+ buf , max_buffer_size = max_buffer_size , flatten = flatten
157
+ )
158
+ )
159
+
160
+
161
+ def ensure_bytes (buf ) -> bytes :
110
162
"""Obtain a bytes object from memory exposed by `buf`."""
111
163
112
164
if not isinstance (buf , bytes ):
113
-
114
- # go via numpy, for convenience
115
- arr = ensure_ndarray (buf )
165
+ arr = ensure_ndarray_like (buf )
116
166
117
167
# check for object arrays, these are just memory pointers,
118
168
# actual memory holding item data is scattered elsewhere
119
169
if arr .dtype == object :
120
- raise TypeError (' object arrays are not supported' )
170
+ raise TypeError (" object arrays are not supported" )
121
171
122
172
# create bytes
123
- buf = arr .tobytes (order = 'A' )
173
+ buf = arr .tobytes (order = "A" )
124
174
125
175
return buf
126
176
127
177
128
- def ensure_text (s , encoding = ' utf-8' ):
178
+ def ensure_text (s , encoding = " utf-8" ):
129
179
if not isinstance (s , str ):
130
180
s = ensure_contiguous_ndarray (s )
131
181
s = codecs .decode (s , encoding )
132
182
return s
133
183
134
184
135
- def ndarray_copy (src , dst ):
185
+ def ndarray_copy (src , dst ) -> NDArrayLike :
136
186
"""Copy the contents of the array from `src` to `dst`."""
137
187
138
188
if dst is None :
139
189
# no-op
140
190
return src
141
191
142
- # ensure ndarrays
143
- src = ensure_ndarray (src )
144
- dst = ensure_ndarray (dst )
192
+ # ensure ndarray like
193
+ src = ensure_ndarray_like (src )
194
+ dst = ensure_ndarray_like (dst )
145
195
146
196
# flatten source array
147
- src = src .reshape (- 1 , order = 'A' )
197
+ src = src .reshape (- 1 , order = "A" )
148
198
149
199
# ensure same data type
150
200
if dst .dtype != object :
@@ -153,9 +203,9 @@ def ndarray_copy(src, dst):
153
203
# reshape source to match destination
154
204
if src .shape != dst .shape :
155
205
if dst .flags .f_contiguous :
156
- order = 'F'
206
+ order = "F"
157
207
else :
158
- order = 'C'
208
+ order = "C"
159
209
src = src .reshape (dst .shape , order = order )
160
210
161
211
# copy via numpy
0 commit comments