Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
checks.pyx382 linesDownload Raw Back to cython
1#cython: language_level=3
2
3"""
4Functions in this module give python-space wrappers for cython functions
5exposed in numpy/__init__.pxd, so they can be tested in test_cython.py
6"""
7import numpy as np
8cimport numpy as cnp
9cnp.import_array()
10
11
12def is_td64(obj):
13    return cnp.is_timedelta64_object(obj)
14
15
16def is_dt64(obj):
17    return cnp.is_datetime64_object(obj)
18
19
20def get_dt64_value(obj):
21    return cnp.get_datetime64_value(obj)
22
23
24def get_td64_value(obj):
25    return cnp.get_timedelta64_value(obj)
26
27
28def get_dt64_unit(obj):
29    return cnp.get_datetime64_unit(obj)
30
31
32def is_integer(obj):
33    return isinstance(obj, (cnp.integer, int))
34
35
36def get_datetime_iso_8601_strlen():
37    return cnp.get_datetime_iso_8601_strlen(0, cnp.NPY_FR_ns)
38
39
40def convert_datetime64_to_datetimestruct():
41    cdef:
42        cnp.npy_datetimestruct dts
43        cnp.PyArray_DatetimeMetaData meta
44        cnp.int64_t value = 1647374515260292
45        # i.e. (time.time() * 10**6) at 2022-03-15 20:01:55.260292 UTC
46
47    meta.base = cnp.NPY_FR_us
48    meta.num = 1
49    cnp.convert_datetime64_to_datetimestruct(&meta, value, &dts)
50    return dts
51
52
53def make_iso_8601_datetime(dt: "datetime"):
54    cdef:
55        cnp.npy_datetimestruct dts
56        char result[36]  # 36 corresponds to NPY_FR_s passed below
57        int local = 0
58        int utc = 0
59        int tzoffset = 0
60
61    dts.year = dt.year
62    dts.month = dt.month
63    dts.day = dt.day
64    dts.hour = dt.hour
65    dts.min = dt.minute
66    dts.sec = dt.second
67    dts.us = dt.microsecond
68    dts.ps = dts.as = 0
69
70    cnp.make_iso_8601_datetime(
71        &dts,
72        result,
73        sizeof(result),
74        local,
75        utc,
76        cnp.NPY_FR_s,
77        tzoffset,
78        cnp.NPY_NO_CASTING,
79    )
80    return result
81
82
83cdef cnp.broadcast multiiter_from_broadcast_obj(object bcast):
84    cdef dict iter_map = {
85        1: cnp.PyArray_MultiIterNew1,
86        2: cnp.PyArray_MultiIterNew2,
87        3: cnp.PyArray_MultiIterNew3,
88        4: cnp.PyArray_MultiIterNew4,
89        5: cnp.PyArray_MultiIterNew5,
90    }
91    arrays = [x.base for x in bcast.iters]
92    cdef cnp.broadcast result = iter_map[len(arrays)](*arrays)
93    return result
94
95
96def get_multiiter_size(bcast: "broadcast"):
97    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
98    return multi.size
99
100
101def get_multiiter_number_of_dims(bcast: "broadcast"):
102    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
103    return multi.nd
104
105
106def get_multiiter_current_index(bcast: "broadcast"):
107    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
108    return multi.index
109
110
111def get_multiiter_num_of_iterators(bcast: "broadcast"):
112    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
113    return multi.numiter
114
115
116def get_multiiter_shape(bcast: "broadcast"):
117    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
118    return tuple([multi.dimensions[i] for i in range(bcast.nd)])
119
120
121def get_multiiter_iters(bcast: "broadcast"):
122    cdef cnp.broadcast multi = multiiter_from_broadcast_obj(bcast)
123    return tuple([<cnp.flatiter>multi.iters[i] for i in range(bcast.numiter)])
124
125
126def get_default_integer():
127    if cnp.NPY_DEFAULT_INT == cnp.NPY_LONG:
128        return cnp.dtype("long")
129    if cnp.NPY_DEFAULT_INT == cnp.NPY_INTP:
130        return cnp.dtype("intp")
131    return None
132
133def get_ravel_axis():
134    return cnp.NPY_RAVEL_AXIS
135
136
137def conv_intp(cnp.intp_t val):
138    return val
139
140
141def get_dtype_flags(cnp.dtype dtype):
142    return dtype.flags
143
144
145cdef cnp.NpyIter* npyiter_from_nditer_obj(object it):
146    """A function to create a NpyIter struct from a nditer object.
147
148    This function is only meant for testing purposes and only extracts the
149    necessary info from nditer to test the functionality of NpyIter methods
150    """
151    cdef:
152        cnp.NpyIter* cit
153        cnp.PyArray_Descr* op_dtypes[3]
154        cnp.npy_uint32 op_flags[3]
155        cnp.PyArrayObject* ops[3]
156        cnp.npy_uint32 flags = 0
157
158    if it.has_index:
159        flags |= cnp.NPY_ITER_C_INDEX
160    if it.has_delayed_bufalloc:
161        flags |= cnp.NPY_ITER_BUFFERED | cnp.NPY_ITER_DELAY_BUFALLOC
162    if it.has_multi_index:
163        flags |= cnp.NPY_ITER_MULTI_INDEX
164
165    # one of READWRITE, READONLY and WRTIEONLY at the minimum must be specified for op_flags
166    for i in range(it.nop):
167        op_flags[i] = cnp.NPY_ITER_READONLY
168
169    for i in range(it.nop):
170        op_dtypes[i] = cnp.PyArray_DESCR(it.operands[i])
171        ops[i] = <cnp.PyArrayObject*>it.operands[i]
172
173    cit = cnp.NpyIter_MultiNew(it.nop, &ops[0], flags, cnp.NPY_KEEPORDER,
174                               cnp.NPY_NO_CASTING, &op_flags[0],
175                               <cnp.PyArray_Descr**>NULL)
176    return cit
177
178
179def get_npyiter_size(it: "nditer"):
180    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
181    result = cnp.NpyIter_GetIterSize(cit)
182    cnp.NpyIter_Deallocate(cit)
183    return result
184
185
186def get_npyiter_ndim(it: "nditer"):
187    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
188    result = cnp.NpyIter_GetNDim(cit)
189    cnp.NpyIter_Deallocate(cit)
190    return result
191
192
193def get_npyiter_nop(it: "nditer"):
194    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
195    result = cnp.NpyIter_GetNOp(cit)
196    cnp.NpyIter_Deallocate(cit)
197    return result
198
199
200def get_npyiter_operands(it: "nditer"):
201    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
202    try:
203        arr = cnp.NpyIter_GetOperandArray(cit)
204        return tuple([<cnp.ndarray>arr[i] for i in range(it.nop)])
205    finally:
206        cnp.NpyIter_Deallocate(cit)
207
208
209def get_npyiter_itviews(it: "nditer"):
210    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
211    result = tuple([cnp.NpyIter_GetIterView(cit, i) for i in range(it.nop)])
212    cnp.NpyIter_Deallocate(cit)
213    return result
214
215
216def get_npyiter_dtypes(it: "nditer"):
217    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
218    try:
219        arr = cnp.NpyIter_GetDescrArray(cit)
220        return tuple([<cnp.dtype>arr[i] for i in range(it.nop)])
221    finally:
222        cnp.NpyIter_Deallocate(cit)
223
224
225def npyiter_has_delayed_bufalloc(it: "nditer"):
226    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
227    result = cnp.NpyIter_HasDelayedBufAlloc(cit)
228    cnp.NpyIter_Deallocate(cit)
229    return result
230
231
232def npyiter_has_index(it: "nditer"):
233    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
234    result = cnp.NpyIter_HasIndex(cit)
235    cnp.NpyIter_Deallocate(cit)
236    return result
237
238
239def npyiter_has_multi_index(it: "nditer"):
240    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
241    result = cnp.NpyIter_HasMultiIndex(cit)
242    cnp.NpyIter_Deallocate(cit)
243    return result
244
245
246def test_get_multi_index_iter_next(it: "nditer", cnp.ndarray[cnp.float64_t, ndim=2] arr):
247    cdef cnp.NpyIter* cit = npyiter_from_nditer_obj(it)
248    cdef cnp.NpyIter_GetMultiIndexFunc _get_multi_index = \
249        cnp.NpyIter_GetGetMultiIndex(cit, NULL)
250    cdef cnp.NpyIter_IterNextFunc _iternext = \
251        cnp.NpyIter_GetIterNext(cit, NULL)
252    cnp.NpyIter_Deallocate(cit)
253    return 1
254
255
256def npyiter_has_finished(it: "nditer"):
257    cdef cnp.NpyIter* cit
258    try:
259        cit = npyiter_from_nditer_obj(it)
260        cnp.NpyIter_GotoIterIndex(cit, it.index)
261        return not (cnp.NpyIter_GetIterIndex(cit) < cnp.NpyIter_GetIterSize(cit))
262    finally:
263        cnp.NpyIter_Deallocate(cit)
264
265def compile_fillwithbyte():
266    # Regression test for gh-25878, mostly checks it compiles.
267    cdef cnp.npy_intp dims[2]
268    dims = (1, 2)
269    pos = cnp.PyArray_ZEROS(2, dims, cnp.NPY_UINT8, 0)
270    cnp.PyArray_FILLWBYTE(pos, 1)
271    return pos
272
273def inc2_cfloat_struct(cnp.ndarray[cnp.cfloat_t] arr):
274    # This works since we compile in C mode, it will fail in cpp mode
275    arr[1].real += 1
276    arr[1].imag += 1
277    # This works in both modes
278    arr[1].real = arr[1].real + 1
279    arr[1].imag = arr[1].imag + 1
280
281
282def npystring_pack(arr):
283    cdef char *string = "Hello world"
284    cdef size_t size = 11
285
286    allocator = cnp.NpyString_acquire_allocator(
287        <cnp.PyArray_StringDTypeObject *>cnp.PyArray_DESCR(arr)
288    )
289
290    # copy string->packed_string, the pointer to the underlying array buffer
291    ret = cnp.NpyString_pack(
292        allocator, <cnp.npy_packed_static_string *>cnp.PyArray_DATA(arr), string, size,
293    )
294
295    cnp.NpyString_release_allocator(allocator)
296    return ret
297
298
299def npystring_load(arr):
300    allocator = cnp.NpyString_acquire_allocator(
301        <cnp.PyArray_StringDTypeObject *>cnp.PyArray_DESCR(arr)
302    )
303
304    cdef cnp.npy_static_string sdata
305    sdata.size = 0
306    sdata.buf = NULL
307
308    cdef cnp.npy_packed_static_string *packed_string = <cnp.npy_packed_static_string *>cnp.PyArray_DATA(arr)
309    cdef int is_null = cnp.NpyString_load(allocator, packed_string, &sdata)
310    cnp.NpyString_release_allocator(allocator)
311    if is_null == -1:
312        raise ValueError("String unpacking failed.")
313    elif is_null == 1:
314        # String in the array buffer is the null string
315        return ""
316    else:
317        # Cython syntax for copying a c string to python bytestring:
318        # slice the char * by the length of the string
319        return sdata.buf[:sdata.size].decode('utf-8')
320
321
322def npystring_pack_multiple(arr1, arr2):
323    cdef cnp.npy_string_allocator *allocators[2]
324    cdef cnp.PyArray_Descr *descrs[2]
325    descrs[0] = cnp.PyArray_DESCR(arr1)
326    descrs[1] = cnp.PyArray_DESCR(arr2)
327
328    cnp.NpyString_acquire_allocators(2, descrs, allocators)
329
330    # Write into the first element of each array
331    cdef int ret1 = cnp.NpyString_pack(
332        allocators[0], <cnp.npy_packed_static_string *>cnp.PyArray_DATA(arr1), "Hello world", 11,
333    )
334    cdef int ret2 = cnp.NpyString_pack(
335        allocators[1], <cnp.npy_packed_static_string *>cnp.PyArray_DATA(arr2), "test this", 9,
336    )
337
338    # Write a null string into the last element
339    cdef cnp.npy_intp elsize = cnp.PyArray_ITEMSIZE(arr1)
340    cdef int ret3 = cnp.NpyString_pack_null(
341        allocators[0],
342        <cnp.npy_packed_static_string *>(<char *>cnp.PyArray_DATA(arr1) + 2*elsize),
343    )
344
345    cnp.NpyString_release_allocators(2, allocators)
346    if ret1 == -1 or ret2 == -1 or ret3 == -1:
347        return -1
348
349    return 0
350
351
352def npystring_allocators_other_types(arr1, arr2):
353    cdef cnp.npy_string_allocator *allocators[2]
354    cdef cnp.PyArray_Descr *descrs[2]
355    descrs[0] = cnp.PyArray_DESCR(arr1)
356    descrs[1] = cnp.PyArray_DESCR(arr2)
357
358    cnp.NpyString_acquire_allocators(2, descrs, allocators)
359
360    # None of the dtypes here are StringDType, so every allocator
361    # should be NULL upon acquisition.
362    cdef int ret = 0
363    for allocator in allocators:
364        if allocator != NULL:
365            ret = -1
366            break
367
368    cnp.NpyString_release_allocators(2, allocators)
369    return ret
370
371
372def check_npy_uintp_type_enum():
373    # Regression test for gh-27890: cnp.NPY_UINTP was not defined.
374    # Cython would fail to compile this before gh-27890 was fixed.
375    return cnp.NPY_UINTP > 0
376
377
378def resize_refcheck_test():
379    # see gh-30991
380    a = np.array([[0, 1], [2, 3]], order='C')
381    a.resize((2, 1))
382 
codekingpro/portable-devtools · Team Ai