summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/src/multiarray/arrayobject.c19
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src28
-rw-r--r--numpy/core/src/multiarray/compiled_base.c21
-rw-r--r--numpy/core/src/multiarray/convert.c21
-rw-r--r--numpy/core/src/multiarray/ctors.c118
-rw-r--r--numpy/core/src/multiarray/ctors.h8
-rw-r--r--numpy/core/src/multiarray/dtype_transfer.c21
-rw-r--r--numpy/core/src/multiarray/einsum.c.src42
-rw-r--r--numpy/core/src/multiarray/getset.c22
-rw-r--r--numpy/core/src/multiarray/item_selection.c26
-rw-r--r--numpy/core/src/multiarray/iterators.c13
-rw-r--r--numpy/core/src/multiarray/mapping.c105
-rw-r--r--numpy/core/src/multiarray/methods.c77
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c23
-rw-r--r--numpy/core/src/multiarray/nditer_api.c18
-rw-r--r--numpy/core/src/multiarray/nditer_pywrap.c22
-rw-r--r--numpy/core/src/multiarray/scalarapi.c15
-rw-r--r--numpy/core/src/multiarray/shape.c65
-rw-r--r--numpy/core/src/umath/reduction.c14
-rw-r--r--numpy/core/tests/test_multiarray.py51
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)