summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Goldbaum <nathan.goldbaum@gmail.com>2023-03-20 12:10:44 -0600
committerNathan Goldbaum <nathan.goldbaum@gmail.com>2023-03-20 12:19:37 -0600
commit4ecdd83851adbd44ce82339ddbae06a422dd7e8d (patch)
tree8d7f999f3ad99bebc0dcd79a0ee28be59b66b50f
parenta1339de171f484651b792eba04b1355acc2a892f (diff)
downloadnumpy-4ecdd83851adbd44ce82339ddbae06a422dd7e8d.tar.gz
MAINT: respond to review comments
-rw-r--r--numpy/core/src/multiarray/ctors.c4
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c40
2 files changed, 27 insertions, 17 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 7107a0538..84d6e80af 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -1934,14 +1934,14 @@ PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth,
int res = PyArray_ExtractDTypeAndDescriptor(
descr, &dt_info.descr, &dt_info.dtype);
+ Py_XDECREF(descr);
+
if (res < 0) {
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return NULL;
}
- Py_XDECREF(descr);
-
PyObject* ret = PyArray_CheckFromAny_int(
op, dt_info.descr, dt_info.dtype, min_depth, max_depth, requires,
context);
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 37c7f14bd..00447bc5f 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -1635,10 +1635,16 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order)
((order) == NPY_CORDER && PyArray_IS_C_CONTIGUOUS(op)) || \
((order) == NPY_FORTRANORDER && PyArray_IS_F_CONTIGUOUS(op)))
+/*
+ * NOTE: in_descr is passed as a reference to a pointer because there is a
+ * code path where the pointer can be changed via Py_XSETREF and we need to
+ * make sure the mutated pointer is available for the caller.
+ */
+
static inline PyObject *
_array_fromobject_generic(
- PyObject *op, npy_dtype_info dt_info, _PyArray_CopyMode copy,
- NPY_ORDER order, npy_bool subok, int ndmin)
+ PyObject *op, PyArray_Descr **in_descr, PyArray_DTypeMeta *in_DType,
+ _PyArray_CopyMode copy, NPY_ORDER order, npy_bool subok, int ndmin)
{
PyArrayObject *oparr = NULL, *ret = NULL;
PyArray_Descr *oldtype = NULL;
@@ -1658,29 +1664,31 @@ _array_fromobject_generic(
* Skip AdaptDescriptorToArray if the supplied dtype class does not
* match the dtype of the input array or if we have to determine the
* descriptor because only the DType was given. This means we avoid
- * inspecting array values twice for example if someone does:
+ * inspecting array values twice if someone does, e.g.:
*
* >>> arr = np.array(["asdf", "fdsa"], dtype=object)
* >>> np.array(arr, dtype="U")
*/
- if ((NPY_DTYPE(PyArray_DESCR(oparr)) == dt_info.dtype) ||
- ((dt_info.descr == NULL) && (dt_info.dtype != NULL))) {
+ if ((NPY_DTYPE(PyArray_DESCR(oparr)) == in_DType) ||
+ ((*in_descr == NULL) && (in_DType != NULL))) {
dtype = PyArray_AdaptDescriptorToArray(
- oparr, dt_info.dtype, dt_info.descr);
+ oparr, in_DType, *in_descr);
if (dtype == NULL) {
return NULL;
}
+ Py_INCREF(dtype);
+ Py_XSETREF(*in_descr, dtype);
}
else {
- if ((dt_info.descr == NULL) && (dt_info.dtype == NULL)) {
+ if ((*in_descr == NULL) && (in_DType == NULL)) {
dtype = PyArray_DESCR(oparr);
}
else {
- dtype = dt_info.descr;
+ dtype = *in_descr;
}
Py_INCREF(dtype);
}
- if ((dt_info.descr == NULL) && (dt_info.dtype == NULL)) {
+ if ((*in_descr == NULL) && (in_DType == NULL)) {
if (copy != NPY_COPY_ALWAYS && STRIDING_OK(oparr, order)) {
ret = oparr;
Py_INCREF(ret);
@@ -1772,7 +1780,7 @@ _array_fromobject_generic(
flags |= NPY_ARRAY_FORCECAST;
ret = (PyArrayObject *)PyArray_CheckFromAny_int(
- op, dt_info.descr, dt_info.dtype, 0, 0, flags, NULL);
+ op, *in_descr, in_DType, 0, 0, flags, NULL);
finish:
if (ret == NULL) {
@@ -1836,7 +1844,7 @@ array_array(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, dt_info, copy, order, subok, ndmin);
+ op, &dt_info.descr, dt_info.dtype, copy, order, subok, ndmin);
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return res;
@@ -1878,7 +1886,7 @@ array_asarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, dt_info, NPY_FALSE, order, NPY_FALSE, 0);
+ op, &dt_info.descr, dt_info.dtype, NPY_FALSE, order, NPY_FALSE, 0);
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return res;
@@ -1920,7 +1928,7 @@ array_asanyarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, dt_info, NPY_FALSE, order, NPY_TRUE, 0);
+ op, &dt_info.descr, dt_info.dtype, NPY_FALSE, order, NPY_TRUE, 0);
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return res;
@@ -1961,7 +1969,8 @@ array_ascontiguousarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, dt_info, NPY_FALSE, NPY_CORDER, NPY_FALSE, 1);
+ op, &dt_info.descr, dt_info.dtype, NPY_FALSE, NPY_CORDER, NPY_FALSE,
+ 1);
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return res;
@@ -2002,7 +2011,8 @@ array_asfortranarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, dt_info, NPY_FALSE, NPY_FORTRANORDER, NPY_FALSE, 1);
+ op, &dt_info.descr, dt_info.dtype, NPY_FALSE, NPY_FORTRANORDER,
+ NPY_FALSE, 1);
Py_XDECREF(dt_info.descr);
Py_XDECREF(dt_info.dtype);
return res;