Commit 94609679 authored by Stefan Behnel's avatar Stefan Behnel

Merge branch 'dalleyg-dtype' of https://github.com/dalleyg/cython into master

parents 71c1ad42 926337d9
......@@ -52,6 +52,8 @@ cdef extern from "numpy/arrayobject.h":
NPY_STRING
NPY_UNICODE
NPY_VOID
NPY_DATETIME
NPY_TIMEDELTA
NPY_NTYPES
NPY_NOTYPE
......@@ -152,11 +154,22 @@ cdef extern from "numpy/arrayobject.h":
ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *, void *)
ctypedef struct PyArray_ArrayDescr:
# shape is a tuple, but Cython doesn't support "tuple shape"
# inside a non-PyObject declaration, so we have to declare it
# as just a PyObject*.
PyObject* shape
ctypedef class numpy.dtype [object PyArray_Descr]:
# Use PyDataType_* macros when possible, however there are no macros
# for accessing some of the fields, so some are defined.
cdef char kind
cdef char type
# Numpy sometimes mutates this without warning (e.g. it'll
# sometimes change "|" to "<" in shared dtype objects on
# little-endian machines). If this matters to you, use
# PyArray_IsNativeByteOrder(dtype.byteorder) instead of
# directly accessing this field.
cdef char byteorder
cdef char flags
cdef int type_num
......@@ -164,6 +177,10 @@ cdef extern from "numpy/arrayobject.h":
cdef int alignment
cdef dict fields
cdef tuple names
# Use PyDataType_HASSUBARRAY to test whether this field is
# valid (the pointer can be NULL). Most users should access
# this field via the inline helper method PyDataType_SHAPE.
cdef PyArray_ArrayDescr* subarray
ctypedef extern class numpy.flatiter [object PyArrayIterObject]:
# Use through macros
......@@ -428,6 +445,7 @@ cdef extern from "numpy/arrayobject.h":
bint PyDataType_ISEXTENDED(dtype)
bint PyDataType_ISOBJECT(dtype)
bint PyDataType_HASFIELDS(dtype)
bint PyDataType_HASSUBARRAY(dtype)
bint PyArray_ISBOOL(ndarray)
bint PyArray_ISUNSIGNED(ndarray)
......@@ -782,6 +800,12 @@ cdef inline object PyArray_MultiIterNew4(a, b, c, d):
cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
cdef inline tuple PyDataType_SHAPE(dtype d):
if PyDataType_HASSUBARRAY(d):
return <tuple>d.subarray.shape
else:
return ()
cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
# Recursive utility function used in __getbuffer__ to get format
# string. The new location in the format string is returned.
......
# tag: numpy
cimport numpy as np
cimport cython
import numpy as py_numpy
__doc__ = u"""
>>> test_record_subarray()
"""
def test_record_subarray():
cdef np.ndarray x = py_numpy.zeros((2,2),
dtype=[('a', py_numpy.int32),
('b', py_numpy.float64, (3, 3))])
cdef np.dtype descr = x.dtype
cdef np.dtype a_descr = descr.fields['a'][0]
cdef np.dtype b_descr = descr.fields['b'][0]
# Make sure the dtype looks like we expect
assert descr.fields == {'a': (py_numpy.dtype('int32'), 0),
'b': (py_numpy.dtype(('<f8', (3, 3))), 4)}
# Make sure that HASSUBARRAY is working
assert not np.PyDataType_HASSUBARRAY(descr)
assert not np.PyDataType_HASSUBARRAY(a_descr)
assert np.PyDataType_HASSUBARRAY(b_descr)
# Make sure the direct field access works
assert <tuple>b_descr.subarray.shape == (3, 3)
# Make sure the safe high-level helper function works
assert np.PyDataType_SHAPE(descr) == ()
assert np.PyDataType_SHAPE(a_descr) == ()
assert np.PyDataType_SHAPE(b_descr) == (3, 3)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment