diff options
author | Mark Wiebe <mwwiebe@gmail.com> | 2011-07-12 18:14:33 -0500 |
---|---|---|
committer | Mark Wiebe <mwiebe@enthought.com> | 2011-07-19 14:00:27 -0500 |
commit | b7cc20ad3400f650bbc45feb5a0bad041722ef29 (patch) | |
tree | a32e348520b3ac3302f707a1eb42244011a23c77 | |
parent | c625ee0c38af6148dd7758d317256f2828646a17 (diff) | |
download | numpy-b7cc20ad3400f650bbc45feb5a0bad041722ef29.tar.gz |
ENH: core: Deprecating direct access to the PyArrayObject fields
NOTE: WIP, code doesn't build
-rw-r--r-- | doc/neps/missing-data.rst | 16 | ||||
-rw-r--r-- | numpy/core/code_generators/generate_numpy_api.py | 4 | ||||
-rw-r--r-- | numpy/core/code_generators/numpy_api.py | 1 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarraytypes.h | 346 | ||||
-rw-r--r-- | numpy/core/include/numpy/npy_deprecated_api.h | 6 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arrayobject.c | 33 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 271 | ||||
-rw-r--r-- | numpy/core/src/multiarray/item_selection.c | 2 |
8 files changed, 421 insertions, 258 deletions
diff --git a/doc/neps/missing-data.rst b/doc/neps/missing-data.rst index e1492cdb3..24071d09c 100644 --- a/doc/neps/missing-data.rst +++ b/doc/neps/missing-data.rst @@ -711,7 +711,7 @@ This gives us the following additions to the PyArrayObject:: PyArray_Descr *maskna_descr; /* * Raw data buffer for mask. If the array has the flag - * NPY_ARRAY_OWNNAMASK enabled, it owns this memory and + * NPY_ARRAY_OWNMASKNA enabled, it owns this memory and * must call PyArray_free on it when destroyed. */ npy_mask *maskna_data; @@ -724,10 +724,10 @@ This gives us the following additions to the PyArrayObject:: There are 2 (or 3) flags which must be added to the array flags:: - NPY_ARRAY_HASNAMASK - NPY_ARRAY_OWNNAMASK + NPY_ARRAY_HASMASKNA + NPY_ARRAY_OWNMASKNA /* To possibly add in a later revision */ - NPY_ARRAY_HARDNAMASK + NPY_ARRAY_HARDMASKNA To allow the easy detection of NA support, and whether an array has any missing values, we add the following functions: @@ -817,7 +817,7 @@ NPY_ITER_ARRAYMASK can be only one such mask, and there cannot also be a virtual mask. - As a special case, if the flag NPY_ITER_USE_NAMASK is specified + As a special case, if the flag NPY_ITER_USE_MASKNA is specified at the same time, the mask for the operand is used instead of the operand itself. If the operand has no mask but is based on an NA dtype, that mask exposed by the iterator converts @@ -837,14 +837,14 @@ Iterator NA-array Features We add several new per-operand flags: -NPY_ITER_USE_NAMASK +NPY_ITER_USE_MASKNA If the operand has an NA dtype, an NA mask, or both, this adds a new virtual operand to the end of the operand list which iterates over the mask of the particular operand. -NPY_ITER_IGNORE_NAMASK +NPY_ITER_IGNORE_MASKNA If an operand has an NA mask, by default the iterator will raise - an exception unless NPY_ITER_USE_NAMASK is specified. This flag + an exception unless NPY_ITER_USE_MASKNA is specified. This flag disables that check, and is intended for cases where one has first checked that all the elements in the array are not NA using the PyArray_ContainsNA function. diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py index 2f4316d17..7cd4b9f6a 100644 --- a/numpy/core/code_generators/generate_numpy_api.py +++ b/numpy/core/code_generators/generate_numpy_api.py @@ -220,7 +220,9 @@ def do_generate_api(targets, sources): for name, index in types_api.items(): multiarray_api_dict[name] = TypeApi(name, index, 'PyTypeObject', api_name) - assert len(multiarray_api_dict) == len(multiarray_api_index) + if len(multiarray_api_dict) != len(multiarray_api_index): + raise AssertionError, "Multiarray API size mismatch %d %d" % \ + (len(multiarray_api_dict), len(multiarray_api_index)) extension_list = [] for name, index in genapi.order_dict(multiarray_api_index): diff --git a/numpy/core/code_generators/numpy_api.py b/numpy/core/code_generators/numpy_api.py index d83371319..08d25d899 100644 --- a/numpy/core/code_generators/numpy_api.py +++ b/numpy/core/code_generators/numpy_api.py @@ -318,6 +318,7 @@ multiarray_funcs_api = { # End 1.6 API 'PyArray_MaskedCopyInto': 281, 'PyArray_MaskedMoveInto': 282, + 'PyArray_SetBase': 283, } ufunc_types_api = { diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h index 0f0673825..7bd455d77 100644 --- a/numpy/core/include/numpy/ndarraytypes.h +++ b/numpy/core/include/numpy/ndarraytypes.h @@ -519,7 +519,7 @@ typedef struct { NPY_ITEM_IS_POINTER | NPY_ITEM_REFCOUNT | \ NPY_NEEDS_INIT | NPY_NEEDS_PYAPI) -#define PyDataType_FLAGCHK(dtype, flag) \ +#define PyDataType_FLAGCHK(dtype, flag) \ (((dtype)->flags & (flag)) == (flag)) #define PyDataType_REFCHK(dtype) \ @@ -573,12 +573,16 @@ typedef struct _arr_descr { } PyArray_ArrayDescr; /* - * The main array object structure. It is recommended to use the macros - * defined below (PyArray_DATA and friends) access fields here, instead - * of the members themselves. + * The main array object structure. + * + * It has been recommended to use the inline functions defined below + * (PyArray_DATA and friends) to access fields here for a number of + * releases. Direct access to the members themselves is deprecated. + * To ensure that your code does not use deprecated access, + * #define NPY_NO_DEPRECATED_API. */ - -typedef struct PyArrayObject { +/* This struct will be moved to a private header in a future release */ +typedef struct tagPyArrayObject_fieldaccess { PyObject_HEAD char *data; /* pointer to raw data buffer */ int nd; /* number of dimensions, also called ndim */ @@ -605,7 +609,21 @@ typedef struct PyArrayObject { PyArray_Descr *descr; /* Pointer to type structure */ int flags; /* Flags describing array -- see below */ PyObject *weakreflist; /* For weakreferences */ +} PyArrayObject_fieldaccess; + +/* + * To hide the implementation details, we only expose + * the Python struct HEAD. + */ +#ifdef NPY_NO_DEPRECATE_API +typedef struct tagPyArrayObject { + PyObject_HEAD } PyArrayObject; +#else +typedef PyArrayObject_fieldaccess PyArrayObject; +#endif + +#define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fieldaccess)) /* Array Flags Object */ typedef struct PyArrayFlagsObject { @@ -785,9 +803,6 @@ typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *); */ -#define PyArray_CHKFLAGS(m, FLAGS) \ - ((((PyArrayObject *)(m))->flags & (FLAGS)) == (FLAGS)) - #define PyArray_ISCONTIGUOUS(m) PyArray_CHKFLAGS(m, NPY_ARRAY_C_CONTIGUOUS) #define PyArray_ISWRITEABLE(m) PyArray_CHKFLAGS(m, NPY_ARRAY_WRITEABLE) #define PyArray_ISALIGNED(m) PyArray_CHKFLAGS(m, NPY_ARRAY_ALIGNED) @@ -939,122 +954,122 @@ struct PyArrayIterObject_tag { #define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) #define _PyAIT(it) ((PyArrayIterObject *)(it)) -#define PyArray_ITER_RESET(it) { \ - _PyAIT(it)->index = 0; \ - _PyAIT(it)->dataptr = _PyAIT(it)->ao->data; \ - memset(_PyAIT(it)->coordinates, 0, \ - (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \ +#define PyArray_ITER_RESET(it) { \ + _PyAIT(it)->index = 0; \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + memset(_PyAIT(it)->coordinates, 0, \ + (_PyAIT(it)->nd_m1+1)*sizeof(npy_intp)); \ } -#define _PyArray_ITER_NEXT1(it) { \ - (it)->dataptr += _PyAIT(it)->strides[0]; \ - (it)->coordinates[0]++; \ +#define _PyArray_ITER_NEXT1(it) { \ + (it)->dataptr += _PyAIT(it)->strides[0]; \ + (it)->coordinates[0]++; \ } -#define _PyArray_ITER_NEXT2(it) { \ - if ((it)->coordinates[1] < (it)->dims_m1[1]) { \ - (it)->coordinates[1]++; \ - (it)->dataptr += (it)->strides[1]; \ - } \ - else { \ - (it)->coordinates[1] = 0; \ - (it)->coordinates[0]++; \ - (it)->dataptr += (it)->strides[0] - \ - (it)->backstrides[1]; \ - } \ +#define _PyArray_ITER_NEXT2(it) { \ + if ((it)->coordinates[1] < (it)->dims_m1[1]) { \ + (it)->coordinates[1]++; \ + (it)->dataptr += (it)->strides[1]; \ + } \ + else { \ + (it)->coordinates[1] = 0; \ + (it)->coordinates[0]++; \ + (it)->dataptr += (it)->strides[0] \ + (it)->backstrides[1]; \ + } \ } -#define _PyArray_ITER_NEXT3(it) { \ - if ((it)->coordinates[2] < (it)->dims_m1[2]) { \ - (it)->coordinates[2]++; \ - (it)->dataptr += (it)->strides[2]; \ - } \ - else { \ - (it)->coordinates[2] = 0; \ - (it)->dataptr -= (it)->backstrides[2]; \ - if ((it)->coordinates[1] < (it)->dims_m1[1]) { \ - (it)->coordinates[1]++; \ - (it)->dataptr += (it)->strides[1]; \ - } \ - else { \ - (it)->coordinates[1] = 0; \ - (it)->coordinates[0]++; \ - (it)->dataptr += (it)->strides[0] - \ - (it)->backstrides[1]; \ - } \ - } \ +#define _PyArray_ITER_NEXT3(it) { \ + if ((it)->coordinates[2] < (it)->dims_m1[2]) { \ + (it)->coordinates[2]++; \ + (it)->dataptr += (it)->strides[2]; \ + } \ + else { \ + (it)->coordinates[2] = 0; \ + (it)->dataptr -= (it)->backstrides[2]; \ + if ((it)->coordinates[1] < (it)->dims_m1[1]) { \ + (it)->coordinates[1]++; \ + (it)->dataptr += (it)->strides[1]; \ + } \ + else { \ + (it)->coordinates[1] = 0; \ + (it)->coordinates[0]++; \ + (it)->dataptr += (it)->strides[0] \ + (it)->backstrides[1]; \ + } \ + } \ } -#define PyArray_ITER_NEXT(it) { \ - _PyAIT(it)->index++; \ - if (_PyAIT(it)->nd_m1 == 0) { \ - _PyArray_ITER_NEXT1(_PyAIT(it)); \ - } \ - else if (_PyAIT(it)->contiguous) \ - _PyAIT(it)->dataptr += _PyAIT(it)->ao->descr->elsize; \ - else if (_PyAIT(it)->nd_m1 == 1) { \ - _PyArray_ITER_NEXT2(_PyAIT(it)); \ - } \ - else { \ - int __npy_i; \ +#define PyArray_ITER_NEXT(it) { \ + _PyAIT(it)->index++; \ + if (_PyAIT(it)->nd_m1 == 0) { \ + _PyArray_ITER_NEXT1(_PyAIT(it)); \ + } \ + else if (_PyAIT(it)->contiguous) \ + _PyAIT(it)->dataptr += PyArray_DESCR(_PyAIT(it)->ao)->elsize; \ + else if (_PyAIT(it)->nd_m1 == 1) { \ + _PyArray_ITER_NEXT2(_PyAIT(it)); \ + } \ + else { \ + int __npy_i; \ for (__npy_i=_PyAIT(it)->nd_m1; __npy_i >= 0; __npy_i--) { \ - if (_PyAIT(it)->coordinates[__npy_i] < \ - _PyAIT(it)->dims_m1[__npy_i]) { \ - _PyAIT(it)->coordinates[__npy_i]++; \ - _PyAIT(it)->dataptr += \ - _PyAIT(it)->strides[__npy_i]; \ - break; \ - } \ - else { \ - _PyAIT(it)->coordinates[__npy_i] = 0; \ - _PyAIT(it)->dataptr -= \ - _PyAIT(it)->backstrides[__npy_i]; \ - } \ - } \ - } \ + if (_PyAIT(it)->coordinates[__npy_i] < \ + _PyAIT(it)->dims_m1[__npy_i]) { \ + _PyAIT(it)->coordinates[__npy_i]++; \ + _PyAIT(it)->dataptr += \ + _PyAIT(it)->strides[__npy_i]; \ + break; \ + } \ + else { \ + _PyAIT(it)->coordinates[__npy_i] = 0; \ + _PyAIT(it)->dataptr -= \ + _PyAIT(it)->backstrides[__npy_i]; \ + } \ + } \ + } \ } -#define PyArray_ITER_GOTO(it, destination) { \ - int __npy_i; \ - _PyAIT(it)->index = 0; \ - _PyAIT(it)->dataptr = _PyAIT(it)->ao->data; \ - for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \ - if (destination[__npy_i] < 0) { \ - destination[__npy_i] += \ - _PyAIT(it)->dims_m1[__npy_i]+1; \ - } \ - _PyAIT(it)->dataptr += destination[__npy_i] * \ - _PyAIT(it)->strides[__npy_i]; \ - _PyAIT(it)->coordinates[__npy_i] = \ - destination[__npy_i]; \ - _PyAIT(it)->index += destination[__npy_i] * \ - ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \ - _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \ - } \ +#define PyArray_ITER_GOTO(it, destination) { \ + int __npy_i; \ + _PyAIT(it)->index = 0; \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + for (__npy_i = _PyAIT(it)->nd_m1; __npy_i>=0; __npy_i--) { \ + if (destination[__npy_i] < 0) { \ + destination[__npy_i] += \ + _PyAIT(it)->dims_m1[__npy_i]+1; \ + } \ + _PyAIT(it)->dataptr += destination[__npy_i] * \ + _PyAIT(it)->strides[__npy_i]; \ + _PyAIT(it)->coordinates[__npy_i] = \ + destination[__npy_i]; \ + _PyAIT(it)->index += destination[__npy_i] * \ + ( __npy_i==_PyAIT(it)->nd_m1 ? 1 : \ + _PyAIT(it)->dims_m1[__npy_i+1]+1) ; \ + } \ } -#define PyArray_ITER_GOTO1D(it, ind) { \ - int __npy_i; \ - npy_intp __npy_ind = (npy_intp) (ind); \ - if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \ - _PyAIT(it)->index = __npy_ind; \ - if (_PyAIT(it)->nd_m1 == 0) { \ - _PyAIT(it)->dataptr = _PyAIT(it)->ao->data + \ - __npy_ind * _PyAIT(it)->strides[0]; \ - } \ - else if (_PyAIT(it)->contiguous) \ - _PyAIT(it)->dataptr = _PyAIT(it)->ao->data + \ - __npy_ind * _PyAIT(it)->ao->descr->elsize; \ - else { \ - _PyAIT(it)->dataptr = _PyAIT(it)->ao->data; \ - for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \ - __npy_i++) { \ - _PyAIT(it)->dataptr += \ +#define PyArray_ITER_GOTO1D(it, ind) { \ + int __npy_i; \ + npy_intp __npy_ind = (npy_intp) (ind); \ + if (__npy_ind < 0) __npy_ind += _PyAIT(it)->size; \ + _PyAIT(it)->index = __npy_ind; \ + if (_PyAIT(it)->nd_m1 == 0) { \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \ + __npy_ind * _PyAIT(it)->strides[0]; \ + } \ + else if (_PyAIT(it)->contiguous) \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao) + \ + __npy_ind * PyArray_DESCR(_PyAIT(it)->ao)->elsize; \ + else { \ + _PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \ + for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \ + __npy_i++) { \ + _PyAIT(it)->dataptr += \ (__npy_ind / _PyAIT(it)->factors[__npy_i]) \ - * _PyAIT(it)->strides[__npy_i]; \ - __npy_ind %= _PyAIT(it)->factors[__npy_i]; \ - } \ - } \ + * _PyAIT(it)->strides[__npy_i]; \ + __npy_ind %= _PyAIT(it)->factors[__npy_i]; \ + } \ + } \ } #define PyArray_ITER_DATA(it) ((void *)(_PyAIT(it)->dataptr)) @@ -1255,27 +1270,96 @@ PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter); NPY_ARRAY_F_CONTIGUOUS : 0)) #define FORTRAN_IF PyArray_FORTRAN_IF -#define PyArray_DATA(obj) ((void *)(((PyArrayObject *)(obj))->data)) -#define PyArray_BYTES(obj) (((PyArrayObject *)(obj))->data) -#define PyArray_DIMS(obj) (((PyArrayObject *)(obj))->dimensions) -#define PyArray_STRIDES(obj) (((PyArrayObject *)(obj))->strides) -#define PyArray_DIM(obj,n) (PyArray_DIMS(obj)[n]) -#define PyArray_STRIDE(obj,n) (PyArray_STRIDES(obj)[n]) -#define PyArray_BASE(obj) (((PyArrayObject *)(obj))->base) -#define PyArray_DESCR(obj) (((PyArrayObject *)(obj))->descr) -#define PyArray_FLAGS(obj) (((PyArrayObject *)(obj))->flags) -#define PyArray_ITEMSIZE(obj) (((PyArrayObject *)(obj))->descr->elsize) -#define PyArray_TYPE(obj) (((PyArrayObject *)(obj))->descr->type_num) - -#define PyArray_GETITEM(obj,itemptr) \ - ((PyArrayObject *)(obj))->descr->f->getitem((char *)(itemptr), \ - (PyArrayObject *)(obj)) - -#define PyArray_SETITEM(obj,itemptr,v) \ - ((PyArrayObject *)(obj))->descr->f->setitem((PyObject *)(v), \ - (char *)(itemptr), \ - (PyArrayObject *)(obj)) +static NPY_INLINE void * +PyArray_DATA(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->data; +} + +static NPY_INLINE char * +PyArray_BYTES(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->data; +} + +static NPY_INLINE npy_intp * +PyArray_DIMS(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->dimensions; +} + +static NPY_INLINE npy_intp * +PyArray_STRIDES(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->strides; +} + +static NPY_INLINE npy_intp +PyArray_DIM(PyArrayObject *arr, int idim) +{ + return ((PyArrayObject_fieldaccess *)arr)->dimensions[idim]; +} + +static NPY_INLINE npy_intp +PyArray_STRIDE(PyArrayObject *arr, int istride) +{ + return ((PyArrayObject_fieldaccess *)arr)->strides[istride]; +} + +static NPY_INLINE PyObject * +PyArray_BASE(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->base; +} + +static NPY_INLINE PyArray_Descr * +PyArray_DESCR(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->descr; +} + +static NPY_INLINE int +PyArray_FLAGS(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->flags; +} + +static NPY_INLINE int +PyArray_CHKFLAGS(PyArrayObject *arr, int flags) +{ + return (PyArray_FLAGS(arr) & flags) == flags; +} + + +static NPY_INLINE npy_intp +PyArray_ITEMSIZE(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->descr->elsize; +} + +static NPY_INLINE int +PyArray_TYPE(PyArrayObject *arr) +{ + return ((PyArrayObject_fieldaccess *)arr)->descr->type_num; +} + +static NPY_INLINE PyObject * +PyArray_GETITEM(PyArrayObject *arr, void *itemptr) +{ + return ((PyArrayObject_fieldaccess *)arr)->descr->f->getitem( + (char *)itemptr, + arr); +} + +static NPY_INLINE int +PyArray_SETITEM(PyArrayObject *arr, void *itemptr, PyObject *v) +{ + return ((PyArrayObject_fieldaccess *)arr)->descr->f->setitem( + v, + (char *)itemptr, + arr); +} #define PyTypeNum_ISBOOL(type) ((type) == NPY_BOOL) diff --git a/numpy/core/include/numpy/npy_deprecated_api.h b/numpy/core/include/numpy/npy_deprecated_api.h index 413d24d4e..6002181d6 100644 --- a/numpy/core/include/numpy/npy_deprecated_api.h +++ b/numpy/core/include/numpy/npy_deprecated_api.h @@ -89,4 +89,10 @@ */ #define fortran fortran_ +/* + * Direct access to PyArrayObject fields is deprecated as of NumPy 1.7, + * but enabled here through this typedef. + */ +typedef PyArrayObject_fieldaccess PyArrayObject; + #endif diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index a1dc4399a..14b4efbf0 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -65,6 +65,35 @@ PyArray_Size(PyObject *op) } } +/*NUMPY_API + * Sets the 'base' attribute of the array. + * + * Returns 0 on success, -1 on failure. + */ +NPY_NO_EXPORT int +PyArray_SetBase(PyArrayObject *arr, PyObject *obj) +{ + /* + * Don't allow chains of views, always set the base + * to the owner of the data + */ + while (PyArray_Check(obj) && + (PyObject *)arr != obj && + PyArray_BASE(obj) != NULL) { + obj = PyArray_BASE(obj); + } + /* Disallow circular references */ + if ((PyObject *)arr == obj) { + PyErr_SetString(PyExc_ValueError, + "Cannot create a circular NumPy array 'base' dependency"); + return -1; + } + ((PyArrayObject_fieldaccess *)arr)->base = obj; + + return 0; +} + + /*NUMPY_API*/ NPY_NO_EXPORT int PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) @@ -1370,7 +1399,7 @@ array_alloc(PyTypeObject *type, Py_ssize_t NPY_UNUSED(nitems)) { PyObject *obj; /* nitems will always be 0 */ - obj = (PyObject *)_pya_malloc(sizeof(PyArrayObject)); + obj = (PyObject *)_pya_malloc(NPY_SIZEOF_PYARRAYOBJECT); PyObject_Init(obj, type); return obj; } @@ -1384,7 +1413,7 @@ NPY_NO_EXPORT PyTypeObject PyArray_Type = { 0, /* ob_size */ #endif "numpy.ndarray", /* tp_name */ - sizeof(PyArrayObject), /* tp_basicsize */ + NPY_SIZEOF_PYARRAYOBJECT, /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)array_dealloc, /* tp_dealloc */ diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index f8362b27f..36154df6e 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -130,7 +130,7 @@ static PyObject * return @func1@((@type1@)t1); } else { - ap->descr->f->copyswap(&t1, ip, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(&t1, ip, !PyArray_ISNOTSWAPPED(ap), ap); return @func1@((@type1@)t1); } } @@ -157,7 +157,7 @@ static int if (ap == NULL || PyArray_ISBEHAVED(ap)) *((@type@ *)ov)=temp; else { - ap->descr->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); } return 0; } @@ -206,8 +206,9 @@ static int if (!(PyArray_IsScalar(op, @kind@))) { if (PyArray_Check(op) && (PyArray_NDIM(op) == 0)) { - op2 = ((PyArrayObject *)op)->descr->f->getitem - (((PyArrayObject *)op)->data, (PyArrayObject *)op); + op2 = PyArray_DESCR((PyArrayObject *)op)->f->getitem( + PyArray_BYTES((PyArrayObject *)op), + (PyArrayObject *)op); } else { op2 = op; Py_INCREF(op); @@ -229,7 +230,7 @@ static int else { temp = ((Py@kind@ScalarObject *)op)->obval; } - memcpy(ov, &temp, ap->descr->elsize); + memcpy(ov, &temp, PyArray_DESCR(ap)->elsize); if (!PyArray_ISNOTSWAPPED(ap)) { byte_swap_vector(ov, 2, sizeof(@type@)); } @@ -247,7 +248,7 @@ static int static PyObject * LONGDOUBLE_getitem(char *ip, PyArrayObject *ap) { - return PyArray_Scalar(ip, ap->descr, NULL); + return PyArray_Scalar(ip, PyArray_DESCR(ap), NULL); } static int @@ -268,7 +269,7 @@ LONGDOUBLE_setitem(PyObject *op, char *ov, PyArrayObject *ap) { *((longdouble *)ov) = temp; } else { - copy_and_swap(ov, &temp, ap->descr->elsize, 1, 0, + copy_and_swap(ov, &temp, PyArray_DESCR(ap)->elsize, 1, 0, !PyArray_ISNOTSWAPPED(ap)); } return 0; @@ -277,14 +278,14 @@ LONGDOUBLE_setitem(PyObject *op, char *ov, PyArrayObject *ap) { static PyObject * CLONGDOUBLE_getitem(char *ip, PyArrayObject *ap) { - return PyArray_Scalar(ip, ap->descr, NULL); + return PyArray_Scalar(ip, PyArray_DESCR(ap), NULL); } /* UNICODE */ static PyObject * UNICODE_getitem(char *ip, PyArrayObject *ap) { - intp elsize = ap->descr->elsize; + intp elsize = PyArray_DESCR(ap)->elsize; intp mysize = elsize/sizeof(PyArray_UCS4); int alloc = 0; PyArray_UCS4 *buffer = NULL; @@ -378,10 +379,10 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap) datalen = PyUnicode_GET_DATA_SIZE(temp); #ifdef Py_UNICODE_WIDE - memcpy(ov, ptr, MIN(ap->descr->elsize, datalen)); + memcpy(ov, ptr, MIN(PyArray_DESCR(ap)->elsize, datalen)); #else if (!PyArray_ISALIGNED(ap)) { - buffer = PyArray_malloc(ap->descr->elsize); + buffer = PyArray_malloc(PyArray_DESCR(ap)->elsize); if (buffer == NULL) { Py_DECREF(temp); PyErr_NoMemory(); @@ -392,7 +393,7 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap) buffer = ov; } datalen = PyUCS2Buffer_AsUCS4(ptr, (PyArray_UCS4 *)buffer, - datalen >> 1, ap->descr->elsize >> 2); + datalen >> 1, PyArray_DESCR(ap)->elsize >> 2); datalen <<= 2; if (!PyArray_ISALIGNED(ap)) { memcpy(ov, buffer, datalen); @@ -400,11 +401,11 @@ UNICODE_setitem(PyObject *op, char *ov, PyArrayObject *ap) } #endif /* Fill in the rest of the space with 0 */ - if (ap->descr->elsize > datalen) { - memset(ov + datalen, 0, (ap->descr->elsize - datalen)); + if (PyArray_DESCR(ap)->elsize > datalen) { + memset(ov + datalen, 0, (PyArray_DESCR(ap)->elsize - datalen)); } if (!PyArray_ISNOTSWAPPED(ap)) { - byte_swap_vector(ov, ap->descr->elsize >> 2, 4); + byte_swap_vector(ov, PyArray_DESCR(ap)->elsize >> 2, 4); } Py_DECREF(temp); return 0; @@ -420,7 +421,7 @@ STRING_getitem(char *ip, PyArrayObject *ap) { /* Will eliminate NULLs at the end */ char *ptr; - int size = ap->descr->elsize; + int size = PyArray_DESCR(ap)->elsize; ptr = ip + size - 1; while (*ptr-- == '\0' && size > 0) { @@ -437,8 +438,8 @@ STRING_setitem(PyObject *op, char *ov, PyArrayObject *ap) PyObject *temp = NULL; /* Handle case of assigning from an array scalar */ - if (PyArray_Check(op) && PyArray_NDIM(op) == 0) { - temp = PyArray_ToScalar(PyArray_DATA(op), op); + if (PyArray_Check(op) && PyArray_NDIM((PyArrayObject *)op) == 0) { + temp = PyArray_ToScalar(PyArray_BYTES((PyArrayObject *)op), op); if (temp == NULL) { return -1; } @@ -489,13 +490,13 @@ STRING_setitem(PyObject *op, char *ov, PyArrayObject *ap) Py_DECREF(temp); return -1; } - memcpy(ov, ptr, MIN(ap->descr->elsize,len)); + memcpy(ov, ptr, MIN(PyArray_DESCR(ap)->elsize,len)); /* * If string lenth is smaller than room in array * Then fill the rest of the element size with NULL */ - if (ap->descr->elsize > len) { - memset(ov + len, 0, (ap->descr->elsize - len)); + if (PyArray_DESCR(ap)->elsize > len) { + memset(ov + len, 0, (PyArray_DESCR(ap)->elsize - len)); } Py_DECREF(temp); return 0; @@ -540,11 +541,11 @@ OBJECT_setitem(PyObject *op, char *ov, PyArrayObject *ap) static PyObject * VOID_getitem(char *ip, PyArrayObject *ap) { - PyObject *u = NULL; + PyArrayObject *u = NULL; PyArray_Descr* descr; int itemsize; - descr = ap->descr; + descr = PyArray_DESCR(ap); if (PyDataType_HASFIELDS(descr)) { PyObject *key; PyObject *names; @@ -559,35 +560,39 @@ VOID_getitem(char *ip, PyArrayObject *ap) names = descr->names; n = PyTuple_GET_SIZE(names); ret = PyTuple_New(n); - savedflags = ap->flags; + savedflags = PyArray_FLAGS(ap); for (i = 0; i < n; i++) { key = PyTuple_GET_ITEM(names, i); tup = PyDict_GetItem(descr->fields, key); if (!PyArg_ParseTuple(tup, "Oi|O", &new, &offset, &title)) { Py_DECREF(ret); - ap->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; return NULL; } - ap->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)ap)->descr = new; /* update alignment based on offset */ if ((new->alignment > 1) && ((((intp)(ip+offset)) % new->alignment) != 0)) { - ap->flags &= ~NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags &= ~NPY_ARRAY_ALIGNED; } else { - ap->flags |= NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags |= NPY_ARRAY_ALIGNED; } PyTuple_SET_ITEM(ret, i, new->f->getitem(ip+offset, ap)); - ap->flags = savedflags; + ((PyArrayObject_fieldaccess *)ap)->flags = savedflags; } - ap->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; return ret; } if (descr->subarray) { /* return an array of the basic type */ PyArray_Dims shape = {NULL, -1}; - PyObject *ret; + PyArrayObject *ret; if (!(PyArray_IntpConverter(descr->subarray->shape, &shape))) { PyDimMem_FREE(shape.ptr); @@ -596,17 +601,20 @@ VOID_getitem(char *ip, PyArrayObject *ap) return NULL; } Py_INCREF(descr->subarray->base); - ret = PyArray_NewFromDescr(&PyArray_Type, + ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, descr->subarray->base, shape.len, shape.ptr, - NULL, ip, ap->flags&(~NPY_ARRAY_F_CONTIGUOUS), NULL); + NULL, ip, PyArray_FLAGS(ap)&(~NPY_ARRAY_F_CONTIGUOUS), NULL); PyDimMem_FREE(shape.ptr); if (!ret) { return NULL; } - PyArray_BASE(ret) = (PyObject *)ap; + if (PyArray_SetBase(ret, (PyObject *)ap) < 0) { + Py_DECREF(ret); + return NULL; + } Py_INCREF(ap); PyArray_UpdateFlags((PyArrayObject *)ret, NPY_ARRAY_UPDATE_ALL); - return ret; + return (PyObject *)ret; } if (PyDataType_FLAGCHK(descr, NPY_ITEM_HASOBJECT) @@ -615,7 +623,7 @@ VOID_getitem(char *ip, PyArrayObject *ap) "tried to get void-array with object members as buffer."); return NULL; } - itemsize = ap->descr->elsize; + itemsize = PyArray_DESCR(ap)->elsize; #if defined(NPY_PY3K) /* * Return a byte array; there are no plain buffer objects on Py3 @@ -625,12 +633,15 @@ VOID_getitem(char *ip, PyArrayObject *ap) PyArray_Descr *descr; dims[0] = itemsize; strides[0] = 1; - descr = PyArray_DescrNewFromType(PyArray_BYTE); - u = PyArray_NewFromDescr(&PyArray_Type, descr, 1, dims, strides, - ip, + descr = PyArray_DescrNewFromType(NPY_BYTE); + u = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, + descr, 1, dims, strides, ip, PyArray_ISWRITEABLE(ap) ? NPY_ARRAY_WRITEABLE : 0, NULL); - ((PyArrayObject*)u)->base = ap; + if (PyArray_SetBase(u, ap) < 0) { + Py_DECREF(u); + return NULL; + } Py_INCREF(ap); } #else @@ -639,19 +650,16 @@ VOID_getitem(char *ip, PyArrayObject *ap) * current item a view of it */ if (PyArray_ISWRITEABLE(ap)) { - u = PyBuffer_FromReadWriteMemory(ip, itemsize); + u = (PyArrayObject *)PyBuffer_FromReadWriteMemory(ip, itemsize); } else { - u = PyBuffer_FromMemory(ip, itemsize); + u = (PyArrayObject *)PyBuffer_FromMemory(ip, itemsize); } #endif if (u == NULL) { - goto fail; + return NULL; } - return u; - -fail: - return NULL; + return (PyObject *)u; } @@ -661,10 +669,10 @@ static int VOID_setitem(PyObject *op, char *ip, PyArrayObject *ap) { PyArray_Descr* descr; - int itemsize=ap->descr->elsize; + int itemsize=PyArray_DESCR(ap)->elsize; int res; - descr = ap->descr; + descr = PyArray_DESCR(ap); if (descr->names && PyTuple_Check(op)) { PyObject *key; PyObject *names; @@ -683,37 +691,41 @@ VOID_setitem(PyObject *op, char *ip, PyArrayObject *ap) "size of tuple must match number of fields."); return -1; } - savedflags = ap->flags; + savedflags = PyArray_FLAGS(ap); for (i = 0; i < n; i++) { key = PyTuple_GET_ITEM(names, i); tup = PyDict_GetItem(descr->fields, key); if (!PyArg_ParseTuple(tup, "Oi|O", &new, &offset, &title)) { - ap->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; return -1; } - ap->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)ap)->descr = new; /* remember to update alignment flags */ if ((new->alignment > 1) && ((((intp)(ip+offset)) % new->alignment) != 0)) { - ap->flags &= ~NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags &= ~NPY_ARRAY_ALIGNED; } else { - ap->flags |= NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags |= NPY_ARRAY_ALIGNED; } res = new->f->setitem(PyTuple_GET_ITEM(op, i), ip+offset, ap); - ap->flags = savedflags; + ((PyArrayObject_fieldaccess *)ap)->flags = savedflags; if (res < 0) { break; } } - ap->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; return res; } if (descr->subarray) { /* copy into an array of the same basic type */ PyArray_Dims shape = {NULL, -1}; - PyObject *ret; + PyArrayObject *ret; if (!(PyArray_IntpConverter(descr->subarray->shape, &shape))) { PyDimMem_FREE(shape.ptr); PyErr_SetString(PyExc_ValueError, @@ -721,17 +733,20 @@ VOID_setitem(PyObject *op, char *ip, PyArrayObject *ap) return -1; } Py_INCREF(descr->subarray->base); - ret = PyArray_NewFromDescr(&PyArray_Type, - descr->subarray->base, shape.len, shape.ptr, - NULL, ip, ap->flags, NULL); + ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, + descr->subarray->base, shape.len, shape.ptr, + NULL, ip, PyArray_FLAGS(ap), NULL); PyDimMem_FREE(shape.ptr); if (!ret) { return -1; } - PyArray_BASE(ret) = (PyObject *)ap; + if (PyArray_SetBase(ret, (PyObject *)ap) < 0) { + Py_DECREF(ret); + return -1; + } Py_INCREF(ap); - PyArray_UpdateFlags((PyArrayObject *)ret, NPY_ARRAY_UPDATE_ALL); - res = PyArray_CopyObject((PyArrayObject *)ret, op); + PyArray_UpdateFlags(ret, NPY_ARRAY_UPDATE_ALL); + res = PyArray_CopyObject(ret, op); Py_DECREF(ret); return res; } @@ -776,7 +791,7 @@ DATETIME_getitem(char *ip, PyArrayObject *ap) { dt = *((npy_datetime *)ip); } else { - ap->descr->f->copyswap(&dt, ip, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(&dt, ip, !PyArray_ISNOTSWAPPED(ap), ap); } return convert_datetime_to_pyobject(dt, meta); @@ -798,7 +813,7 @@ TIMEDELTA_getitem(char *ip, PyArrayObject *ap) { td = *((npy_timedelta *)ip); } else { - ap->descr->f->copyswap(&td, ip, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(&td, ip, !PyArray_ISNOTSWAPPED(ap), ap); } return convert_timedelta_to_pyobject(td, meta); @@ -827,7 +842,7 @@ DATETIME_setitem(PyObject *op, char *ov, PyArrayObject *ap) { *((npy_datetime *)ov)=temp; } else { - ap->descr->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); } return 0; @@ -856,7 +871,7 @@ TIMEDELTA_setitem(PyObject *op, char *ov, PyArrayObject *ap) { *((npy_timedelta *)ov)=temp; } else { - ap->descr->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); } return 0; @@ -1137,7 +1152,7 @@ static void * longlong, ulonglong, npy_half, float, double, longdouble, * cfloat, cdouble, clongdouble, char, char, char, PyObject *, * datetime, timedelta# - * #skip = 1*18, aip->descr->elsize*3, 1*3# + * #skip = 1*18, PyArray_DESCR(aip)->elsize*3, 1*3# */ static void @FROMTYPE@_to_OBJECT(@fromtype@ *ip, PyObject **op, intp n, PyArrayObject *aip, @@ -1187,7 +1202,7 @@ static void * longlong, ulonglong, npy_half, float, double, longdouble, * cfloat, cdouble, clongdouble, char, char, char, datetime, * timedelta# - * #skip = 1*18, aop->descr->elsize*3, 1*2# + * #skip = 1*18, PyArray_DESCR(aop)->elsize*3, 1*2# */ static void OBJECT_to_@TOTYPE@(PyObject **ip, @totype@ *op, intp n, @@ -1214,7 +1229,9 @@ OBJECT_to_@TOTYPE@(PyObject **ip, @totype@ *op, intp n, * #fromtyp = char*69# * #to = (BOOL, BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, LONGLONG, ULONGLONG, HALF, FLOAT, DOUBLE, LONGDOUBLE, CFLOAT, CDOUBLE, CLONGDOUBLE, STRING, UNICODE, VOID, DATETIME, TIMEDELTA)*3# * #totyp = (Bool, byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, npy_half, float, double, longdouble, cfloat, cdouble, clongdouble, char, char, char, datetime, timedelta)*3# - * #oskip = (1*18,aop->descr->elsize*3,1*2)*3# + * #oskip = 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2, + * 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2, + * 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2# * #convert = 1*18, 0*3, 1*2, 1*18, 0*3, 1*2, 0*23# * #convstr = (Int*9, Long*2, Float*4, Complex*3, Tuple*3, Long*2)*3# */ @@ -1224,7 +1241,7 @@ static void { intp i; PyObject *temp = NULL; - int skip = aip->descr->elsize; + int skip = PyArray_DESCR(aip)->elsize; int oskip = @oskip@; for (i = 0; i < n; i++, ip+=skip, op+=oskip) { @@ -1280,7 +1297,7 @@ static void intp i; PyObject *temp = NULL; int skip = 1; - int oskip = aop->descr->elsize; + int oskip = PyArray_DESCR(aop)->elsize; for (i = 0; i < n; i++, ip += skip, op += oskip) { temp = @from@_getitem((char *)ip, aip); if (temp == NULL) { @@ -1793,7 +1810,7 @@ STRING_copyswapn (char *dst, intp dstride, char *src, intp sstride, intp n, int NPY_UNUSED(swap), PyArrayObject *arr) { if (src != NULL && arr != NULL) { - int itemsize = arr->descr->elsize; + int itemsize = PyArray_DESCR(arr)->elsize; if (dstride == itemsize && sstride == itemsize) { memcpy(dst, src, itemsize * n); @@ -1820,33 +1837,41 @@ VOID_copyswapn (char *dst, intp dstride, char *src, intp sstride, int offset; Py_ssize_t pos = 0; - descr = arr->descr; + descr = PyArray_DESCR(arr); while (PyDict_Next(descr->fields, &pos, &key, &value)) { if NPY_TITLE_KEY(key, value) { continue; } if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset, &title)) { - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } - arr->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)arr)->descr = new; new->f->copyswapn(dst+offset, dstride, (src != NULL ? src+offset : NULL), sstride, n, swap, arr); } - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } - if (swap && arr->descr->subarray != NULL) { + if (swap && PyArray_DESCR(arr)->subarray != NULL) { PyArray_Descr *descr, *new; npy_intp num; npy_intp i; int subitemsize; char *dstptr, *srcptr; - descr = arr->descr; + descr = PyArray_DESCR(arr); new = descr->subarray->base; - arr->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)arr)->descr = new; dstptr = dst; srcptr = src; subitemsize = new->elsize; @@ -1859,11 +1884,11 @@ VOID_copyswapn (char *dst, intp dstride, char *src, intp sstride, srcptr += sstride; } } - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } if (src != NULL) { - memcpy(dst, src, arr->descr->elsize * n); + memcpy(dst, src, PyArray_DESCR(arr)->elsize * n); } return; } @@ -1880,40 +1905,48 @@ VOID_copyswap (char *dst, char *src, int swap, PyArrayObject *arr) int offset; Py_ssize_t pos = 0; - descr = arr->descr; + descr = PyArray_DESCR(arr); while (PyDict_Next(descr->fields, &pos, &key, &value)) { if NPY_TITLE_KEY(key, value) { continue; } if (!PyArg_ParseTuple(value, "Oi|O", &new, &offset, &title)) { - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } - arr->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)arr)->descr = new; new->f->copyswap(dst+offset, (src != NULL ? src+offset : NULL), swap, arr); } - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } - if (swap && arr->descr->subarray != NULL) { + if (swap && PyArray_DESCR(arr)->subarray != NULL) { PyArray_Descr *descr, *new; npy_intp num; int itemsize; - descr = arr->descr; + descr = PyArray_DESCR(arr); new = descr->subarray->base; - arr->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)arr)->descr = new; itemsize = new->elsize; num = descr->elsize / itemsize; new->f->copyswapn(dst, itemsize, src, itemsize, num, swap, arr); - arr->descr = descr; + ((PyArrayObject_fieldaccess *)arr)->descr = descr; return; } if (src != NULL) { - memcpy(dst, src, arr->descr->elsize); + memcpy(dst, src, PyArray_DESCR(arr)->elsize); } return; } @@ -1928,7 +1961,7 @@ UNICODE_copyswapn (char *dst, intp dstride, char *src, intp sstride, if (arr == NULL) { return; } - itemsize = arr->descr->elsize; + itemsize = PyArray_DESCR(arr)->elsize; if (src != NULL) { if (dstride == itemsize && sstride == itemsize) { memcpy(dst, src, n * itemsize); @@ -1963,7 +1996,7 @@ static void STRING_copyswap(char *dst, char *src, int NPY_UNUSED(swap), PyArrayObject *arr) { if (src != NULL && arr != NULL) { - memcpy(dst, src, arr->descr->elsize); + memcpy(dst, src, PyArray_DESCR(arr)->elsize); } } @@ -1975,7 +2008,7 @@ UNICODE_copyswap (char *dst, char *src, int swap, PyArrayObject *arr) if (arr == NULL) { return; } - itemsize = arr->descr->elsize; + itemsize = PyArray_DESCR(arr)->elsize; if (src != NULL) { memcpy(dst, src, itemsize); } @@ -2031,7 +2064,7 @@ static Bool */ @type@ tmp; #if @isfloat@ - ap->descr->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap); #else memcpy(&tmp, ip, sizeof(@type@)); #endif @@ -2054,7 +2087,7 @@ static Bool } else { @type@ tmp; - ap->descr->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap); + PyArray_DESCR(ap)->f->copyswap(&tmp, ip, !PyArray_ISNOTSWAPPED(ap), ap); return (Bool) ((tmp.real != 0) || (tmp.imag != 0)); } } @@ -2083,7 +2116,7 @@ Py_STRING_ISSPACE(char ch) static Bool STRING_nonzero (char *ip, PyArrayObject *ap) { - int len = ap->descr->elsize; + int len = PyArray_DESCR(ap)->elsize; int i; Bool nonz = FALSE; @@ -2106,17 +2139,17 @@ STRING_nonzero (char *ip, PyArrayObject *ap) static Bool UNICODE_nonzero (PyArray_UCS4 *ip, PyArrayObject *ap) { - int len = ap->descr->elsize >> 2; + int len = PyArray_DESCR(ap)->elsize >> 2; int i; Bool nonz = FALSE; char *buffer = NULL; if ((!PyArray_ISNOTSWAPPED(ap)) || (!PyArray_ISALIGNED(ap))) { - buffer = PyArray_malloc(ap->descr->elsize); + buffer = PyArray_malloc(PyArray_DESCR(ap)->elsize); if (buffer == NULL) { return nonz; } - memcpy(buffer, ip, ap->descr->elsize); + memcpy(buffer, ip, PyArray_DESCR(ap)->elsize); if (!PyArray_ISNOTSWAPPED(ap)) { byte_swap_vector(buffer, len, 4); } @@ -2170,8 +2203,8 @@ VOID_nonzero (char *ip, PyArrayObject *ap) int savedflags, offset; Py_ssize_t pos = 0; - descr = ap->descr; - savedflags = ap->flags; + descr = PyArray_DESCR(ap); + savedflags = PyArray_FLAGS(ap); while (PyDict_Next(descr->fields, &pos, &key, &value)) { if NPY_TITLE_KEY(key, value) { continue; @@ -2181,24 +2214,28 @@ VOID_nonzero (char *ip, PyArrayObject *ap) PyErr_Clear(); continue; } - ap->descr = new; - ap->flags = savedflags; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)ap)->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->flags = savedflags; if ((new->alignment > 1) && !__ALIGNED(ip+offset, new->alignment)) { - ap->flags &= ~NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags &= ~NPY_ARRAY_ALIGNED; } else { - ap->flags |= NPY_ARRAY_ALIGNED; + ((PyArrayObject_fieldaccess *)ap)->flags |= NPY_ARRAY_ALIGNED; } if (new->f->nonzero(ip+offset, ap)) { nonz = TRUE; break; } } - ap->descr = descr; - ap->flags = savedflags; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->flags = savedflags; return nonz; } - len = ap->descr->elsize; + len = PyArray_DESCR(ap)->elsize; for (i = 0; i < len; i++) { if (*ip != '\0') { nonz = TRUE; @@ -2413,7 +2450,7 @@ STRING_compare(char *ip1, char *ip2, PyArrayObject *ap) { const unsigned char *c1 = (unsigned char *)ip1; const unsigned char *c2 = (unsigned char *)ip2; - const size_t len = ap->descr->elsize; + const size_t len = PyArray_DESCR(ap)->elsize; size_t i; for(i = 0; i < len; ++i) { @@ -2431,7 +2468,7 @@ static int UNICODE_compare(PyArray_UCS4 *ip1, PyArray_UCS4 *ip2, PyArrayObject *ap) { - int itemsize = ap->descr->elsize; + int itemsize = PyArray_DESCR(ap)->elsize; if (itemsize < 0) { return 0; @@ -2469,7 +2506,7 @@ VOID_compare(char *ip1, char *ip2, PyArrayObject *ap) if (!PyArray_HASFIELDS(ap)) { return STRING_compare(ip1, ip2, ap); } - descr = ap->descr; + descr = PyArray_DESCR(ap); /* * Compare on the first-field. If equal, then * compare on the second-field, etc. @@ -2481,7 +2518,11 @@ VOID_compare(char *ip1, char *ip2, PyArrayObject *ap) if (!PyArg_ParseTuple(tup, "Oi|O", &new, &offset, &title)) { goto finish; } - ap->descr = new; + /* + * TODO: temporarily modifying the array like this + * is bad coding style, should be changed. + */ + ((PyArrayObject_fieldaccess *)ap)->descr = new; swap = PyArray_ISBYTESWAPPED(ap); nip1 = ip1+offset; nip2 = ip2+offset; @@ -2525,7 +2566,7 @@ VOID_compare(char *ip1, char *ip2, PyArrayObject *ap) } finish: - ap->descr = descr; + ((PyArrayObject_fieldaccess *)ap)->descr = descr; return res; } @@ -2648,7 +2689,7 @@ static int @fname@_argmax(@type@ *ip, intp n, intp *max_ind, PyArrayObject *aip) { intp i; - int elsize = aip->descr->elsize; + int elsize = PyArray_DESCR(aip)->elsize; @type@ *mp = (@type@ *)PyArray_malloc(elsize); if (mp==NULL) return 0; diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c index 74203774c..dcab069aa 100644 --- a/numpy/core/src/multiarray/item_selection.c +++ b/numpy/core/src/multiarray/item_selection.c @@ -1187,7 +1187,7 @@ PyArray_LexSort(PyObject *sort_keys, int axis) "need sequence of keys with len > 0 in lexsort"); return NULL; } - mps = (PyArrayObject **) _pya_malloc(n*sizeof(PyArrayObject)); + mps = (PyArrayObject **) _pya_malloc(n*NPY_SIZEOF_PYARRAYOBJECT); if (mps == NULL) { return PyErr_NoMemory(); } |