diff options
Diffstat (limited to 'numpy/core')
20 files changed, 298 insertions, 431 deletions
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index e1db4d6f6..943edc772 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -1620,7 +1620,7 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) PyArray_NewFromDescr_int(subtype, descr, (int)dims.len, dims.ptr, - strides.ptr, NULL, is_f_order, NULL, + strides.ptr, NULL, is_f_order, NULL, NULL, 0, 1); if (ret == NULL) { descr = NULL; @@ -1653,22 +1653,15 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) if (is_f_order) { buffer.flags |= NPY_ARRAY_F_CONTIGUOUS; } - ret = (PyArrayObject *)\ - PyArray_NewFromDescr_int(subtype, descr, - dims.len, dims.ptr, - strides.ptr, - offset + (char *)buffer.ptr, - buffer.flags, NULL, 0, 1); + ret = (PyArrayObject *)PyArray_NewFromDescr_int( + subtype, descr, + dims.len, dims.ptr, strides.ptr, offset + (char *)buffer.ptr, + buffer.flags, NULL, buffer.base, + 0, 1); if (ret == NULL) { descr = NULL; goto fail; } - Py_INCREF(buffer.base); - if (PyArray_SetBaseObject(ret, buffer.base) < 0) { - Py_DECREF(ret); - ret = NULL; - goto fail; - } } npy_free_cache_dim_obj(dims); diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 48003e6a3..b4158ec8e 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -724,18 +724,12 @@ VOID_getitem(void *input, void *vap) return NULL; } Py_INCREF(descr->subarray->base); - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, - descr->subarray->base, shape.len, shape.ptr, - NULL, ip, PyArray_FLAGS(ap)&(~NPY_ARRAY_F_CONTIGUOUS), NULL); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, descr->subarray->base, + shape.len, shape.ptr, NULL, ip, + PyArray_FLAGS(ap) & ~NPY_ARRAY_F_CONTIGUOUS, + NULL, (PyObject *)ap); npy_free_cache_dim_obj(shape); - if (!ret) { - return NULL; - } - Py_INCREF(ap); - if (PyArray_SetBaseObject(ret, (PyObject *)ap) < 0) { - Py_DECREF(ret); - return NULL; - } return (PyObject *)ret; } @@ -923,18 +917,14 @@ VOID_setitem(PyObject *op, void *input, void *vap) return -1; } Py_INCREF(descr->subarray->base); - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, - descr->subarray->base, shape.len, shape.ptr, - NULL, ip, PyArray_FLAGS(ap), NULL); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, descr->subarray->base, + shape.len, shape.ptr, NULL, ip, + PyArray_FLAGS(ap), NULL, (PyObject *)ap); npy_free_cache_dim_obj(shape); if (!ret) { return -1; } - Py_INCREF(ap); - if (PyArray_SetBaseObject(ret, (PyObject *)ap) < 0) { - Py_DECREF(ret); - return -1; - } res = PyArray_CopyObject(ret, op); Py_DECREF(ret); return res; diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c index 25e3dcca3..bcb44f6d1 100644 --- a/numpy/core/src/multiarray/compiled_base.c +++ b/numpy/core/src/multiarray/compiled_base.c @@ -11,6 +11,7 @@ #include "templ_common.h" /* for npy_mul_with_overflow_intp */ #include "lowlevel_strided_loops.h" /* for npy_bswap8 */ #include "alloc.h" +#include "ctors.h" #include "common.h" @@ -273,19 +274,14 @@ arr_digitize(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) npy_intp stride = -PyArray_STRIDE(arr_bins, 0); void *data = (void *)(PyArray_BYTES(arr_bins) - stride * (shape - 1)); - arr_tmp = (PyArrayObject *)PyArray_NewFromDescr( + arr_tmp = (PyArrayObject *)PyArray_NewFromDescrAndBase( &PyArray_Type, PyArray_DescrFromType(NPY_DOUBLE), 1, &shape, &stride, data, - PyArray_FLAGS(arr_bins), NULL); + PyArray_FLAGS(arr_bins), NULL, (PyObject *)arr_bins); + Py_DECREF(arr_bins); if (!arr_tmp) { goto fail; } - - if (PyArray_SetBaseObject(arr_tmp, (PyObject *)arr_bins) < 0) { - - Py_DECREF(arr_tmp); - goto fail; - } arr_bins = arr_tmp; } @@ -1363,19 +1359,14 @@ arr_unravel_index(PyObject *self, PyObject *args, PyObject *kwds) for (i = 0; i < dimensions.len; ++i) { PyArrayObject *view; - view = (PyArrayObject *)PyArray_NewFromDescr( + view = (PyArrayObject *)PyArray_NewFromDescrAndBase( &PyArray_Type, PyArray_DescrFromType(NPY_INTP), ret_ndim - 1, ret_dims, ret_strides, PyArray_BYTES(ret_arr) + i*sizeof(npy_intp), - NPY_ARRAY_WRITEABLE, NULL); + NPY_ARRAY_WRITEABLE, NULL, (PyObject *)ret_arr); if (view == NULL) { goto fail; } - Py_INCREF(ret_arr); - if (PyArray_SetBaseObject(view, (PyObject *)ret_arr) < 0) { - Py_DECREF(view); - goto fail; - } PyTuple_SET_ITEM(ret_tuple, i, PyArray_Return(view)); } diff --git a/numpy/core/src/multiarray/convert.c b/numpy/core/src/multiarray/convert.c index ca30d3f88..0e38aaa61 100644 --- a/numpy/core/src/multiarray/convert.c +++ b/numpy/core/src/multiarray/convert.c @@ -631,26 +631,17 @@ PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject *pytype) dtype = PyArray_DESCR(self); Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr_int(subtype, - dtype, - PyArray_NDIM(self), PyArray_DIMS(self), - PyArray_STRIDES(self), - PyArray_DATA(self), - flags, - (PyObject *)self, 0, 1); + ret = (PyArrayObject *)PyArray_NewFromDescr_int( + subtype, dtype, + PyArray_NDIM(self), PyArray_DIMS(self), PyArray_STRIDES(self), + PyArray_DATA(self), + flags, (PyObject *)self, (PyObject *)self, + 0, 1); if (ret == NULL) { Py_XDECREF(type); return NULL; } - /* Set the base object */ - Py_INCREF(self); - if (PyArray_SetBaseObject(ret, (PyObject *)self) < 0) { - Py_DECREF(ret); - Py_XDECREF(type); - return NULL; - } - if (type != NULL) { if (PyObject_SetAttrString((PyObject *)ret, "dtype", (PyObject *)type) < 0) { diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 70f5c72aa..cdef899a0 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -903,7 +903,7 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it, NPY_NO_EXPORT PyObject * PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, npy_intp *dims, npy_intp *strides, void *data, - int flags, PyObject *obj, int zeroed, + int flags, PyObject *obj, PyObject *base, int zeroed, int allow_emptystring) { PyArrayObject_fields *fa; @@ -921,10 +921,11 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, } nd =_update_descr_and_dimensions(&descr, newdims, newstrides, nd); - ret = PyArray_NewFromDescr_int(subtype, descr, nd, newdims, - newstrides, - data, flags, obj, zeroed, - allow_emptystring); + ret = PyArray_NewFromDescr_int( + subtype, descr, + nd, newdims, newstrides, data, + flags, obj, base, + zeroed, allow_emptystring); return ret; } @@ -1089,6 +1090,16 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, */ PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_UPDATE_ALL); + /* Set the base object. It's important to do it here so that + * __array_finalize__ below receives it + */ + if (base != NULL) { + Py_INCREF(base); + if (PyArray_SetBaseObject((PyArrayObject *)fa, base) < 0) { + goto fail; + } + } + /* * call the __array_finalize__ * method if a subtype. @@ -1147,9 +1158,24 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, npy_intp *dims, npy_intp *strides, void *data, int flags, PyObject *obj) { + return PyArray_NewFromDescrAndBase( + subtype, descr, + nd, dims, strides, data, + flags, obj, NULL); +} + +/* + * Sets the base object using PyArray_SetBaseObject + */ +NPY_NO_EXPORT PyObject * +PyArray_NewFromDescrAndBase( + PyTypeObject *subtype, PyArray_Descr *descr, + int nd, npy_intp *dims, npy_intp *strides, void *data, + int flags, PyObject *obj, PyObject *base) +{ return PyArray_NewFromDescr_int(subtype, descr, nd, dims, strides, data, - flags, obj, 0, 0); + flags, obj, base, 0, 0); } /*NUMPY_API @@ -1349,15 +1375,11 @@ _array_from_buffer_3118(PyObject *memoryview) } flags = NPY_ARRAY_BEHAVED & (view->readonly ? ~NPY_ARRAY_WRITEABLE : ~0); - r = PyArray_NewFromDescr(&PyArray_Type, descr, - nd, shape, strides, view->buf, - flags, NULL); - if (r == NULL) { - goto fail; - } - if (PyArray_SetBaseObject((PyArrayObject *)r, memoryview) < 0) { - goto fail; - } + r = PyArray_NewFromDescrAndBase( + &PyArray_Type, descr, + nd, shape, strides, view->buf, + flags, NULL, memoryview); + Py_DECREF(memoryview); return r; fail: @@ -2112,15 +2134,10 @@ PyArray_FromStructInterface(PyObject *input) } } - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, thetype, - inter->nd, inter->shape, - inter->strides, inter->data, - inter->flags, NULL); - Py_INCREF(input); - if (PyArray_SetBaseObject(ret, input) < 0) { - Py_DECREF(ret); - return NULL; - } + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, thetype, + inter->nd, inter->shape, inter->strides, inter->data, + inter->flags, NULL, input); Py_DECREF(attr); return (PyObject *)ret; @@ -2382,10 +2399,10 @@ PyArray_FromInterface(PyObject *origin) } } - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, - n, dims, - NULL, data, - dataflags, NULL); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, dtype, + n, dims, NULL, data, + dataflags, NULL, base); if (ret == NULL) { goto fail; } @@ -2401,13 +2418,6 @@ PyArray_FromInterface(PyObject *origin) goto fail; } } - if (base) { - Py_INCREF(base); - if (PyArray_SetBaseObject(ret, base) < 0) { - Py_DECREF(ret); - goto fail; - } - } attr = PyDict_GetItemString(iface, "strides"); if (attr != NULL && attr != Py_None) { if (!PyTuple_Check(attr)) { @@ -2898,11 +2908,11 @@ PyArray_Zeros(int nd, npy_intp *dims, PyArray_Descr *type, int is_f_order) type = PyArray_DescrFromType(NPY_DEFAULT_TYPE); } - ret = (PyArrayObject *)PyArray_NewFromDescr_int(&PyArray_Type, - type, - nd, dims, - NULL, NULL, - is_f_order, NULL, 1, 0); + ret = (PyArrayObject *)PyArray_NewFromDescr_int( + &PyArray_Type, type, + nd, dims, NULL, NULL, + is_f_order, NULL, NULL, + 1, 0); if (ret == NULL) { return NULL; @@ -3512,11 +3522,11 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep) } if (dtype->elsize == 0) { /* Nothing to read, just create an empty array of the requested type */ - return PyArray_NewFromDescr_int(&PyArray_Type, - dtype, - 1, &num, - NULL, NULL, - 0, NULL, 0, 1); + return PyArray_NewFromDescr_int( + &PyArray_Type, dtype, + 1, &num, NULL, NULL, + 0, NULL, NULL, + 0, 1); } if ((sep == NULL) || (strlen(sep) == 0)) { ret = array_fromfile_binary(fp, dtype, num, &nread); @@ -3666,24 +3676,18 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, } } - if ((ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, - type, - 1, &n, - NULL, data, - NPY_ARRAY_DEFAULT, - NULL)) == NULL) { - Py_DECREF(buf); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, type, + 1, &n, NULL, data, + NPY_ARRAY_DEFAULT, NULL, buf); + Py_DECREF(buf); + if (ret == NULL) { return NULL; } if (!writeable) { PyArray_CLEARFLAGS(ret, NPY_ARRAY_WRITEABLE); } - /* Store a reference for decref on deallocation */ - if (PyArray_SetBaseObject(ret, buf) < 0) { - Py_DECREF(ret); - return NULL; - } return (PyObject *)ret; } diff --git a/numpy/core/src/multiarray/ctors.h b/numpy/core/src/multiarray/ctors.h index e889910cb..e9a2532da 100644 --- a/numpy/core/src/multiarray/ctors.h +++ b/numpy/core/src/multiarray/ctors.h @@ -7,9 +7,15 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, int flags, PyObject *obj); NPY_NO_EXPORT PyObject * +PyArray_NewFromDescrAndBase( + PyTypeObject *subtype, PyArray_Descr *descr, + int nd, npy_intp *dims, npy_intp *strides, void *data, + int flags, PyObject *obj, PyObject *base); + +NPY_NO_EXPORT PyObject * PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd, npy_intp *dims, npy_intp *strides, void *data, - int flags, PyObject *obj, int zeroed, + int flags, PyObject *obj, PyObject *base, int zeroed, int allow_emptystring); NPY_NO_EXPORT PyObject *PyArray_New(PyTypeObject *, int nd, npy_intp *, diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c index 9f9aa6757..2cb1e0a95 100644 --- a/numpy/core/src/multiarray/dtype_transfer.c +++ b/numpy/core/src/multiarray/dtype_transfer.c @@ -591,8 +591,11 @@ wrap_copy_swap_function(int aligned, * The copyswap functions shouldn't need that. */ Py_INCREF(dtype); - data->arr = (PyArrayObject *)PyArray_NewFromDescr_int(&PyArray_Type, dtype, - 1, &shape, NULL, NULL, 0, NULL, 0, 1); + data->arr = (PyArrayObject *)PyArray_NewFromDescr_int( + &PyArray_Type, dtype, + 1, &shape, NULL, NULL, + 0, NULL, NULL, + 0, 1); if (data->arr == NULL) { PyArray_free(data); return NPY_FAIL; @@ -1447,8 +1450,11 @@ get_nbo_cast_transfer_function(int aligned, return NPY_FAIL; } } - data->aip = (PyArrayObject *)PyArray_NewFromDescr_int(&PyArray_Type, - tmp_dtype, 1, &shape, NULL, NULL, 0, NULL, 0, 1); + data->aip = (PyArrayObject *)PyArray_NewFromDescr_int( + &PyArray_Type, tmp_dtype, + 1, &shape, NULL, NULL, + 0, NULL, NULL, + 0, 1); if (data->aip == NULL) { PyArray_free(data); return NPY_FAIL; @@ -1471,8 +1477,11 @@ get_nbo_cast_transfer_function(int aligned, return NPY_FAIL; } } - data->aop = (PyArrayObject *)PyArray_NewFromDescr_int(&PyArray_Type, - tmp_dtype, 1, &shape, NULL, NULL, 0, NULL, 0, 1); + data->aop = (PyArrayObject *)PyArray_NewFromDescr_int( + &PyArray_Type, tmp_dtype, + 1, &shape, NULL, NULL, + 0, NULL, NULL, + 0, 1); if (data->aop == NULL) { Py_DECREF(data->aip); PyArray_free(data); diff --git a/numpy/core/src/multiarray/einsum.c.src b/numpy/core/src/multiarray/einsum.c.src index 3c086351f..69833bee6 100644 --- a/numpy/core/src/multiarray/einsum.c.src +++ b/numpy/core/src/multiarray/einsum.c.src @@ -23,6 +23,7 @@ #include "convert.h" #include "common.h" +#include "ctors.h" #ifdef NPY_HAVE_SSE_INTRINSICS #define EINSUM_USE_SSE1 1 @@ -2067,23 +2068,16 @@ get_single_op_view(PyArrayObject *op, int iop, char *labels, /* If we processed all the input axes, return a view */ if (idim == ndim) { Py_INCREF(PyArray_DESCR(op)); - *ret = (PyArrayObject *)PyArray_NewFromDescr( - Py_TYPE(op), - PyArray_DESCR(op), - ndim_output, new_dims, new_strides, - PyArray_DATA(op), - PyArray_ISWRITEABLE(op) ? NPY_ARRAY_WRITEABLE : 0, - (PyObject *)op); + *ret = (PyArrayObject *)PyArray_NewFromDescr_int( + Py_TYPE(op), PyArray_DESCR(op), + ndim_output, new_dims, new_strides, PyArray_DATA(op), + PyArray_ISWRITEABLE(op) ? NPY_ARRAY_WRITEABLE : 0, + (PyObject *)op, (PyObject *)op, + 0, 0); if (*ret == NULL) { return -1; } - Py_INCREF(op); - if (PyArray_SetBaseObject(*ret, (PyObject *)op) < 0) { - Py_DECREF(*ret); - *ret = NULL; - return -1; - } return 0; } @@ -2161,23 +2155,11 @@ get_combined_dims_view(PyArrayObject *op, int iop, char *labels) ndim = icombine; Py_INCREF(PyArray_DESCR(op)); - ret = (PyArrayObject *)PyArray_NewFromDescr( - Py_TYPE(op), - PyArray_DESCR(op), - ndim, new_dims, new_strides, - PyArray_DATA(op), - PyArray_ISWRITEABLE(op) ? NPY_ARRAY_WRITEABLE : 0, - (PyObject *)op); - - if (ret == NULL) { - return NULL; - } - Py_INCREF(op); - if (PyArray_SetBaseObject(ret, (PyObject *)op) < 0) { - Py_DECREF(ret); - return NULL; - } - + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + Py_TYPE(op), PyArray_DESCR(op), + ndim, new_dims, new_strides, PyArray_DATA(op), + PyArray_ISWRITEABLE(op) ? NPY_ARRAY_WRITEABLE : 0, + (PyObject *)op, (PyObject *)op); return ret; } diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c index d86f90a53..cae4273ff 100644 --- a/numpy/core/src/multiarray/getset.c +++ b/numpy/core/src/multiarray/getset.c @@ -13,6 +13,7 @@ #include "npy_import.h" #include "common.h" +#include "ctors.h" #include "scalartypes.h" #include "descriptor.h" #include "getset.h" @@ -742,22 +743,17 @@ _get_part(PyArrayObject *self, int imag) Py_DECREF(type); type = new; } - ret = (PyArrayObject *) - PyArray_NewFromDescr(Py_TYPE(self), - type, - PyArray_NDIM(self), - PyArray_DIMS(self), - PyArray_STRIDES(self), - PyArray_BYTES(self) + offset, - PyArray_FLAGS(self), (PyObject *)self); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + Py_TYPE(self), + type, + PyArray_NDIM(self), + PyArray_DIMS(self), + PyArray_STRIDES(self), + PyArray_BYTES(self) + offset, + PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self); if (ret == NULL) { return NULL; } - Py_INCREF(self); - if (PyArray_SetBaseObject(ret, (PyObject *)self) < 0) { - Py_DECREF(ret); - return NULL; - } return ret; } diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c index d010b2e75..141b2d922 100644 --- a/numpy/core/src/multiarray/item_selection.c +++ b/numpy/core/src/multiarray/item_selection.c @@ -1876,21 +1876,13 @@ PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int axis2) /* Create the diagonal view */ dtype = PyArray_DTYPE(self); Py_INCREF(dtype); - ret = PyArray_NewFromDescr(Py_TYPE(self), - dtype, - ndim-1, ret_shape, - ret_strides, - data, - PyArray_FLAGS(self), - (PyObject *)self); + ret = PyArray_NewFromDescrAndBase( + Py_TYPE(self), dtype, + ndim-1, ret_shape, ret_strides, data, + PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self); if (ret == NULL) { return NULL; } - Py_INCREF(self); - if (PyArray_SetBaseObject((PyArrayObject *)ret, (PyObject *)self) < 0) { - Py_DECREF(ret); - return NULL; - } /* * For numpy 1.9 the diagonal view is not writeable. @@ -2365,21 +2357,15 @@ finish: /* the result is an empty array, the view must point to valid memory */ npy_intp data_offset = is_empty ? 0 : i * NPY_SIZEOF_INTP; - PyArrayObject *view = (PyArrayObject *)PyArray_NewFromDescr( + PyArrayObject *view = (PyArrayObject *)PyArray_NewFromDescrAndBase( Py_TYPE(ret), PyArray_DescrFromType(NPY_INTP), 1, &nonzero_count, &stride, PyArray_BYTES(ret) + data_offset, - PyArray_FLAGS(ret), (PyObject *)ret); + PyArray_FLAGS(ret), (PyObject *)ret, (PyObject *)ret); if (view == NULL) { Py_DECREF(ret); Py_DECREF(ret_tuple); return NULL; } - Py_INCREF(ret); - if (PyArray_SetBaseObject(view, (PyObject *)ret) < 0) { - Py_DECREF(ret); - Py_DECREF(ret_tuple); - return NULL; - } PyTuple_SET_ITEM(ret_tuple, i, (PyObject *)view); } Py_DECREF(ret); diff --git a/numpy/core/src/multiarray/iterators.c b/numpy/core/src/multiarray/iterators.c index 723c565f0..3e3248f53 100644 --- a/numpy/core/src/multiarray/iterators.c +++ b/numpy/core/src/multiarray/iterators.c @@ -1092,18 +1092,13 @@ iter_array(PyArrayIterObject *it, PyObject *NPY_UNUSED(op)) Py_INCREF(PyArray_DESCR(it->ao)); if (PyArray_ISCONTIGUOUS(it->ao)) { - ret = (PyArrayObject *)PyArray_NewFromDescr( - &PyArray_Type, PyArray_DESCR(it->ao), 1, &size, - NULL, PyArray_DATA(it->ao), PyArray_FLAGS(it->ao), - (PyObject *)it->ao); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, PyArray_DESCR(it->ao), + 1, &size, NULL, PyArray_DATA(it->ao), + PyArray_FLAGS(it->ao), (PyObject *)it->ao, (PyObject *)it->ao); if (ret == NULL) { return NULL; } - Py_INCREF(it->ao); - if (PyArray_SetBaseObject(ret, (PyObject *)it->ao) < 0) { - Py_DECREF(ret); - return NULL; - } } else { ret = (PyArrayObject *)PyArray_NewFromDescr( diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c index f2782ff27..6a7ffd39d 100644 --- a/numpy/core/src/multiarray/mapping.c +++ b/numpy/core/src/multiarray/mapping.c @@ -980,23 +980,17 @@ get_view_from_index(PyArrayObject *self, PyArrayObject **view, /* Create the new view and set the base array */ Py_INCREF(PyArray_DESCR(self)); - *view = (PyArrayObject *)PyArray_NewFromDescr( - ensure_array ? &PyArray_Type : Py_TYPE(self), - PyArray_DESCR(self), - new_dim, new_shape, - new_strides, data_ptr, - PyArray_FLAGS(self), - ensure_array ? NULL : (PyObject *)self); + *view = (PyArrayObject *)PyArray_NewFromDescrAndBase( + ensure_array ? &PyArray_Type : Py_TYPE(self), + PyArray_DESCR(self), + new_dim, new_shape, new_strides, data_ptr, + PyArray_FLAGS(self), + ensure_array ? NULL : (PyObject *)self, + (PyObject *)self); if (*view == NULL) { return -1; } - Py_INCREF(self); - if (PyArray_SetBaseObject(*view, (PyObject *)self) < 0) { - Py_DECREF(*view); - return -1; - } - return 0; } @@ -1127,19 +1121,15 @@ array_boolean_subscript(PyArrayObject *self, PyArrayObject *tmp = ret; Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), dtype, 1, - &size, PyArray_STRIDES(ret), PyArray_BYTES(ret), - PyArray_FLAGS(self), (PyObject *)self); + ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( + Py_TYPE(self), dtype, + 1, &size, PyArray_STRIDES(ret), PyArray_BYTES(ret), + PyArray_FLAGS(self), (PyObject *)self, (PyObject *)self); if (ret == NULL) { Py_DECREF(tmp); return NULL; } - - if (PyArray_SetBaseObject(ret, (PyObject *)tmp) < 0) { - Py_DECREF(ret); - return NULL; - } } return ret; @@ -1430,22 +1420,18 @@ _get_field_view(PyArrayObject *arr, PyObject *ind, PyArrayObject **view) /* view the array at the new offset+dtype */ Py_INCREF(fieldtype); *view = (PyArrayObject*)PyArray_NewFromDescr_int( - Py_TYPE(arr), - fieldtype, - PyArray_NDIM(arr), - PyArray_SHAPE(arr), - PyArray_STRIDES(arr), - PyArray_BYTES(arr) + offset, - PyArray_FLAGS(arr), - (PyObject *)arr, 0, 1); + Py_TYPE(arr), + fieldtype, + PyArray_NDIM(arr), + PyArray_SHAPE(arr), + PyArray_STRIDES(arr), + PyArray_BYTES(arr) + offset, + PyArray_FLAGS(arr), + (PyObject *)arr, (PyObject *)arr, + 0, 1); if (*view == NULL) { return 0; } - Py_INCREF(arr); - if (PyArray_SetBaseObject(*view, (PyObject *)arr) < 0) { - Py_DECREF(*view); - *view = NULL; - } return 0; } /* next check for a list of field names */ @@ -1557,24 +1543,18 @@ _get_field_view(PyArrayObject *arr, PyObject *ind, PyArrayObject **view) view_dtype->flags = PyArray_DESCR(arr)->flags; *view = (PyArrayObject*)PyArray_NewFromDescr_int( - Py_TYPE(arr), - view_dtype, - PyArray_NDIM(arr), - PyArray_SHAPE(arr), - PyArray_STRIDES(arr), - PyArray_DATA(arr), - PyArray_FLAGS(arr), - (PyObject *)arr, 0, 1); + Py_TYPE(arr), + view_dtype, + PyArray_NDIM(arr), + PyArray_SHAPE(arr), + PyArray_STRIDES(arr), + PyArray_DATA(arr), + PyArray_FLAGS(arr), + (PyObject *)arr, (PyObject *)arr, + 0, 1); if (*view == NULL) { return 0; } - Py_INCREF(arr); - if (PyArray_SetBaseObject(*view, (PyObject *)arr) < 0) { - Py_DECREF(*view); - *view = NULL; - return 0; - } - return 0; } return -1; @@ -1772,24 +1752,17 @@ array_subscript(PyArrayObject *self, PyObject *op) PyArrayObject *tmp_arr = (PyArrayObject *)result; Py_INCREF(PyArray_DESCR(tmp_arr)); - result = PyArray_NewFromDescr(Py_TYPE(self), - PyArray_DESCR(tmp_arr), - PyArray_NDIM(tmp_arr), - PyArray_SHAPE(tmp_arr), - PyArray_STRIDES(tmp_arr), - PyArray_BYTES(tmp_arr), - PyArray_FLAGS(self), - (PyObject *)self); - + result = PyArray_NewFromDescrAndBase( + Py_TYPE(self), + PyArray_DESCR(tmp_arr), + PyArray_NDIM(tmp_arr), + PyArray_SHAPE(tmp_arr), + PyArray_STRIDES(tmp_arr), + PyArray_BYTES(tmp_arr), + PyArray_FLAGS(self), + (PyObject *)self, (PyObject *)tmp_arr); + Py_DECREF(tmp_arr); if (result == NULL) { - Py_DECREF(tmp_arr); - goto finish; - } - - if (PyArray_SetBaseObject((PyArrayObject *)result, - (PyObject *)tmp_arr) < 0) { - Py_DECREF(result); - result = NULL; goto finish; } } diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index ed339b98d..d6f2577a3 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -373,21 +373,13 @@ PyArray_GetField(PyArrayObject *self, PyArray_Descr *typed, int offset) Py_DECREF(safe); } - ret = PyArray_NewFromDescr_int(Py_TYPE(self), - typed, - PyArray_NDIM(self), PyArray_DIMS(self), - PyArray_STRIDES(self), - PyArray_BYTES(self) + offset, - PyArray_FLAGS(self)&(~NPY_ARRAY_F_CONTIGUOUS), - (PyObject *)self, 0, 1); - if (ret == NULL) { - return NULL; - } - Py_INCREF(self); - if (PyArray_SetBaseObject(((PyArrayObject *)ret), (PyObject *)self) < 0) { - Py_DECREF(ret); - return NULL; - } + ret = PyArray_NewFromDescr_int( + Py_TYPE(self), typed, + PyArray_NDIM(self), PyArray_DIMS(self), PyArray_STRIDES(self), + PyArray_BYTES(self) + offset, + PyArray_FLAGS(self) & ~NPY_ARRAY_F_CONTIGUOUS, + (PyObject *)self, (PyObject *)self, + 0, 1); return ret; } @@ -858,7 +850,7 @@ array_astype(PyArrayObject *self, PyObject *args, PyObject *kwds) static PyObject * array_wraparray(PyArrayObject *self, PyObject *args) { - PyArrayObject *arr, *ret; + PyArrayObject *arr; PyObject *obj; if (PyTuple_Size(args) < 1) { @@ -877,24 +869,16 @@ array_wraparray(PyArrayObject *self, PyObject *args) } arr = (PyArrayObject *)obj; - if (Py_TYPE(self) != Py_TYPE(arr)){ + if (Py_TYPE(self) != Py_TYPE(arr)) { PyArray_Descr *dtype = PyArray_DESCR(arr); Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), - dtype, - PyArray_NDIM(arr), - PyArray_DIMS(arr), - PyArray_STRIDES(arr), PyArray_DATA(arr), - PyArray_FLAGS(arr), (PyObject *)self); - if (ret == NULL) { - return NULL; - } - Py_INCREF(obj); - if (PyArray_SetBaseObject(ret, obj) < 0) { - Py_DECREF(ret); - return NULL; - } - return (PyObject *)ret; + return PyArray_NewFromDescrAndBase( + Py_TYPE(self), + dtype, + PyArray_NDIM(arr), + PyArray_DIMS(arr), + PyArray_STRIDES(arr), PyArray_DATA(arr), + PyArray_FLAGS(arr), (PyObject *)self, obj); } else { /*The type was set in __array_prepare__*/ Py_INCREF(arr); @@ -907,7 +891,7 @@ static PyObject * array_preparearray(PyArrayObject *self, PyObject *args) { PyObject *obj; - PyArrayObject *arr, *ret; + PyArrayObject *arr; PyArray_Descr *dtype; if (PyTuple_Size(args) < 1) { @@ -931,21 +915,11 @@ array_preparearray(PyArrayObject *self, PyObject *args) dtype = PyArray_DESCR(arr); Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(self), - dtype, - PyArray_NDIM(arr), - PyArray_DIMS(arr), - PyArray_STRIDES(arr), PyArray_DATA(arr), - PyArray_FLAGS(arr), (PyObject *)self); - if (ret == NULL) { - return NULL; - } - Py_INCREF(arr); - if (PyArray_SetBaseObject(ret, (PyObject *)arr) < 0) { - Py_DECREF(ret); - return NULL; - } - return (PyObject *)ret; + return PyArray_NewFromDescrAndBase( + Py_TYPE(self), dtype, + PyArray_NDIM(arr), PyArray_DIMS(arr), PyArray_STRIDES(arr), + PyArray_DATA(arr), + PyArray_FLAGS(arr), (PyObject *)self, (PyObject *)arr); } @@ -966,7 +940,7 @@ array_getarray(PyArrayObject *self, PyObject *args) PyArrayObject *new; Py_INCREF(PyArray_DESCR(self)); - new = (PyArrayObject *)PyArray_NewFromDescr( + new = (PyArrayObject *)PyArray_NewFromDescrAndBase( &PyArray_Type, PyArray_DESCR(self), PyArray_NDIM(self), @@ -974,13 +948,12 @@ array_getarray(PyArrayObject *self, PyObject *args) PyArray_STRIDES(self), PyArray_DATA(self), PyArray_FLAGS(self), - NULL + NULL, + (PyObject *)self ); if (new == NULL) { return NULL; } - Py_INCREF(self); - PyArray_SetBaseObject(new, (PyObject *)self); self = new; } else { diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index 896a3b07e..f78a748c0 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -1607,7 +1607,7 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order) npy_intp newstrides[NPY_MAXDIMS]; npy_intp newstride; int i, k, num; - PyArrayObject *ret; + PyObject *ret; PyArray_Descr *dtype; if (order == NPY_FORTRANORDER || PyArray_ISFORTRAN(arr) || PyArray_NDIM(arr) == 0) { @@ -1629,22 +1629,13 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order) } dtype = PyArray_DESCR(arr); Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(arr), - dtype, ndmin, newdims, newstrides, - PyArray_DATA(arr), - PyArray_FLAGS(arr), - (PyObject *)arr); - if (ret == NULL) { - Py_DECREF(arr); - return NULL; - } - /* steals a reference to arr --- so don't increment here */ - if (PyArray_SetBaseObject(ret, (PyObject *)arr) < 0) { - Py_DECREF(ret); - return NULL; - } + ret = PyArray_NewFromDescrAndBase( + Py_TYPE(arr), dtype, + ndmin, newdims, newstrides, PyArray_DATA(arr), + PyArray_FLAGS(arr), (PyObject *)arr, (PyObject *)arr); + Py_DECREF(arr); - return (PyObject *)ret; + return ret; } diff --git a/numpy/core/src/multiarray/nditer_api.c b/numpy/core/src/multiarray/nditer_api.c index 28020f79a..ba9e9f273 100644 --- a/numpy/core/src/multiarray/nditer_api.c +++ b/numpy/core/src/multiarray/nditer_api.c @@ -15,6 +15,7 @@ #define NPY_ITERATOR_IMPLEMENTATION_CODE #include "nditer_impl.h" #include "templ_common.h" +#include "ctors.h" /* Internal helper functions private to this file */ static npy_intp @@ -1140,19 +1141,10 @@ NpyIter_GetIterView(NpyIter *iter, npy_intp i) } Py_INCREF(dtype); - view = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, ndim, - shape, strides, dataptr, - writeable ? NPY_ARRAY_WRITEABLE : 0, - NULL); - if (view == NULL) { - return NULL; - } - /* Tell the view who owns the data */ - Py_INCREF(obj); - if (PyArray_SetBaseObject(view, (PyObject *)obj) < 0) { - Py_DECREF(view); - return NULL; - } + view = (PyArrayObject *)PyArray_NewFromDescrAndBase( + &PyArray_Type, dtype, + ndim, shape, strides, dataptr, + writeable ? NPY_ARRAY_WRITEABLE : 0, NULL, (PyObject *)obj); return view; } diff --git a/numpy/core/src/multiarray/nditer_pywrap.c b/numpy/core/src/multiarray/nditer_pywrap.c index 50a138167..0b6c80c8a 100644 --- a/numpy/core/src/multiarray/nditer_pywrap.c +++ b/numpy/core/src/multiarray/nditer_pywrap.c @@ -17,6 +17,7 @@ #include "npy_pycompat.h" #include "alloc.h" #include "common.h" +#include "ctors.h" typedef struct NewNpyArrayIterObject_tag NewNpyArrayIterObject; @@ -1991,8 +1992,6 @@ npyiter_seq_length(NewNpyArrayIterObject *self) NPY_NO_EXPORT PyObject * npyiter_seq_item(NewNpyArrayIterObject *self, Py_ssize_t i) { - PyArrayObject *ret; - npy_intp ret_ndim; npy_intp nop, innerloopsize, innerstride; char *dataptr; @@ -2064,20 +2063,11 @@ npyiter_seq_item(NewNpyArrayIterObject *self, Py_ssize_t i) } Py_INCREF(dtype); - ret = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, - ret_ndim, &innerloopsize, - &innerstride, dataptr, - self->writeflags[i] ? NPY_ARRAY_WRITEABLE : 0, NULL); - if (ret == NULL) { - return NULL; - } - Py_INCREF(self); - if (PyArray_SetBaseObject(ret, (PyObject *)self) < 0) { - Py_XDECREF(ret); - return NULL; - } - - return (PyObject *)ret; + return PyArray_NewFromDescrAndBase( + &PyArray_Type, dtype, + ret_ndim, &innerloopsize, &innerstride, dataptr, + self->writeflags[i] ? NPY_ARRAY_WRITEABLE : 0, + NULL, (PyObject *)self); } NPY_NO_EXPORT PyObject * diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c index 1941f849f..5ef6c0bbf 100644 --- a/numpy/core/src/multiarray/scalarapi.c +++ b/numpy/core/src/multiarray/scalarapi.c @@ -290,21 +290,12 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode) if ((typecode->type_num == NPY_VOID) && !(((PyVoidScalarObject *)scalar)->flags & NPY_ARRAY_OWNDATA) && outcode == NULL) { - r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, - typecode, + return PyArray_NewFromDescrAndBase( + &PyArray_Type, typecode, 0, NULL, NULL, ((PyVoidScalarObject *)scalar)->obval, ((PyVoidScalarObject *)scalar)->flags, - NULL); - if (r == NULL) { - return NULL; - } - Py_INCREF(scalar); - if (PyArray_SetBaseObject(r, (PyObject *)scalar) < 0) { - Py_DECREF(r); - return NULL; - } - return (PyObject *)r; + NULL, (PyObject *)scalar); } /* Need to INCREF typecode because PyArray_NewFromDescr steals a diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c index 1424a69f3..3ac71e285 100644 --- a/numpy/core/src/multiarray/shape.c +++ b/numpy/core/src/multiarray/shape.c @@ -267,26 +267,13 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, } Py_INCREF(PyArray_DESCR(self)); - ret = (PyArrayObject *)PyArray_NewFromDescr_int(Py_TYPE(self), - PyArray_DESCR(self), - ndim, dimensions, - strides, - PyArray_DATA(self), - flags, (PyObject *)self, 0, 1); - - if (ret == NULL) { - goto fail; - } - - if (PyArray_SetBaseObject(ret, (PyObject *)self)) { - Py_DECREF(ret); - return NULL; - } - return (PyObject *)ret; - - fail: + ret = (PyArrayObject *)PyArray_NewFromDescr_int( + Py_TYPE(self), PyArray_DESCR(self), + ndim, dimensions, strides, PyArray_DATA(self), + flags, (PyObject *)self, (PyObject *)self, + 0, 1); Py_DECREF(self); - return NULL; + return (PyObject *)ret; } @@ -714,22 +701,13 @@ PyArray_Transpose(PyArrayObject *ap, PyArray_Dims *permute) * incorrectly), sets up descr, and points data at PyArray_DATA(ap). */ Py_INCREF(PyArray_DESCR(ap)); - ret = (PyArrayObject *) - PyArray_NewFromDescr(Py_TYPE(ap), - PyArray_DESCR(ap), - n, PyArray_DIMS(ap), - NULL, PyArray_DATA(ap), - flags, - (PyObject *)ap); + ret = (PyArrayObject *) PyArray_NewFromDescrAndBase( + Py_TYPE(ap), PyArray_DESCR(ap), + n, PyArray_DIMS(ap), NULL, PyArray_DATA(ap), + flags, (PyObject *)ap, (PyObject *)ap); if (ret == NULL) { return NULL; } - /* point at true owner of memory: */ - Py_INCREF(ap); - if (PyArray_SetBaseObject(ret, (PyObject *)ap) < 0) { - Py_DECREF(ret); - return NULL; - } /* fix the dimensions and strides of the return-array */ for (i = 0; i < n; i++) { @@ -948,29 +926,14 @@ PyArray_Ravel(PyArrayObject *arr, NPY_ORDER order) /* If all the strides matched a contiguous layout, return a view */ if (i < 0) { - PyArrayObject *ret; - stride = PyArray_ITEMSIZE(arr); val[0] = PyArray_SIZE(arr); Py_INCREF(PyArray_DESCR(arr)); - ret = (PyArrayObject *)PyArray_NewFromDescr(Py_TYPE(arr), - PyArray_DESCR(arr), - 1, val, - &stride, - PyArray_BYTES(arr), - PyArray_FLAGS(arr), - (PyObject *)arr); - if (ret == NULL) { - return NULL; - } - Py_INCREF(arr); - if (PyArray_SetBaseObject(ret, (PyObject *)arr) < 0) { - Py_DECREF(ret); - return NULL; - } - - return (PyObject *)ret; + return PyArray_NewFromDescrAndBase( + Py_TYPE(arr), PyArray_DESCR(arr), + 1, val, &stride, PyArray_BYTES(arr), + PyArray_FLAGS(arr), (PyObject *)arr, (PyObject *)arr); } } diff --git a/numpy/core/src/umath/reduction.c b/numpy/core/src/umath/reduction.c index 5c3a84e21..8136d7b3f 100644 --- a/numpy/core/src/umath/reduction.c +++ b/numpy/core/src/umath/reduction.c @@ -155,13 +155,13 @@ conform_reduce_result(int ndim, npy_bool *axis_flags, dtype = PyArray_DESCR(out); Py_INCREF(dtype); - ret = (PyArrayObject_fields *)PyArray_NewFromDescr(&PyArray_Type, - dtype, - ndim, shape, - strides, - PyArray_DATA(out), - PyArray_FLAGS(out), - NULL); + /* TODO: use PyArray_NewFromDescrAndBase here once multiarray and umath + * are merged + */ + ret = (PyArrayObject_fields *)PyArray_NewFromDescr( + &PyArray_Type, dtype, + ndim, shape, strides, PyArray_DATA(out), + PyArray_FLAGS(out), NULL); if (ret == NULL) { return NULL; } diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 77f2f3259..1bca46bf7 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -17,6 +17,7 @@ import functools import ctypes import os import gc +import weakref import pytest from contextlib import contextmanager if sys.version_info[0] >= 3: @@ -7362,6 +7363,56 @@ class TestArange(object): assert_raises(ZeroDivisionError, np.arange, 0.0, 0.0, 0.0) +class TestArrayFinalize(object): + """ Tests __array_finalize__ """ + + def test_receives_base(self): + # gh-11237 + class SavesBase(np.ndarray): + def __array_finalize__(self, obj): + self.saved_base = self.base + + a = np.array(1).view(SavesBase) + assert_(a.saved_base is a.base) + + def test_lifetime_on_error(self): + # gh-11237 + class RaisesInFinalize(np.ndarray): + def __array_finalize__(self, obj): + # crash, but keep this object alive + raise Exception(self) + + # a plain object can't be weakref'd + class Dummy(object): pass + + # get a weak reference to an object within an array + obj_arr = np.array(Dummy()) + obj_ref = weakref.ref(obj_arr[()]) + + # get an array that crashed in __array_finalize__ + with assert_raises(Exception) as e: + obj_arr.view(RaisesInFinalize) + if sys.version_info.major == 2: + # prevent an extra reference being kept + sys.exc_clear() + + obj_subarray = e.exception.args[0] + del e + assert_(isinstance(obj_subarray, RaisesInFinalize)) + + # reference should still be held by obj_arr + gc.collect() + assert_(obj_ref() is not None, "object should not already be dead") + + del obj_arr + gc.collect() + assert_(obj_ref() is not None, "obj_arr should not hold the last reference") + + del obj_subarray + gc.collect() + assert_(obj_ref() is None, "no references should remain") + + def test_orderconverter_with_nonASCII_unicode_ordering(): # gh-7475 a = np.arange(5) |