summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2023-03-23 09:51:27 +0100
committerGitHub <noreply@github.com>2023-03-23 09:51:27 +0100
commit3ede0d999ea55c07adad0097cef330a61e02a88c (patch)
tree065afa1754b531713b9a872dbe1fd447e3067b7a /numpy/core/src
parentb35aac2c35ccfd5efadd7f72a090c9ad99308a60 (diff)
parente05361dc84532fb106ef1c4d1357df5517e126b6 (diff)
downloadnumpy-3ede0d999ea55c07adad0097cef330a61e02a88c.tar.gz
Merge pull request #23404 from ngoldbaum/dtype-class-array-creation
ENH: allow using dtype classes in array creation functions
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/common/ucsnarrow.h2
-rw-r--r--numpy/core/src/multiarray/array_coercion.c9
-rw-r--r--numpy/core/src/multiarray/ctors.c99
-rw-r--r--numpy/core/src/multiarray/ctors.h10
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c130
5 files changed, 179 insertions, 71 deletions
diff --git a/numpy/core/src/common/ucsnarrow.h b/numpy/core/src/common/ucsnarrow.h
index 6fe157199..4b17a2809 100644
--- a/numpy/core/src/common/ucsnarrow.h
+++ b/numpy/core/src/common/ucsnarrow.h
@@ -2,6 +2,6 @@
#define NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_
NPY_NO_EXPORT PyUnicodeObject *
-PyUnicode_FromUCS4(char *src, Py_ssize_t size, int swap, int align);
+PyUnicode_FromUCS4(char const *src, Py_ssize_t size, int swap, int align);
#endif /* NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_ */
diff --git a/numpy/core/src/multiarray/array_coercion.c b/numpy/core/src/multiarray/array_coercion.c
index d6bee1a7b..d55a5752b 100644
--- a/numpy/core/src/multiarray/array_coercion.c
+++ b/numpy/core/src/multiarray/array_coercion.c
@@ -878,7 +878,8 @@ find_descriptor_from_array(
* means that legacy behavior is used: The dtype instances "S0", "U0", and
* "V0" are converted to mean the DType classes instead.
* When dtype != NULL, this path is ignored, and the function does nothing
- * unless descr == NULL.
+ * unless descr == NULL. If both descr and dtype are null, it returns the
+ * descriptor for the array.
*
* This function is identical to normal casting using only the dtype, however,
* it supports inspecting the elements when the array has object dtype
@@ -927,7 +928,7 @@ PyArray_AdaptDescriptorToArray(
/* This is an object array but contained no elements, use default */
new_descr = NPY_DT_CALL_default_descr(dtype);
}
- Py_DECREF(dtype);
+ Py_XDECREF(dtype);
return new_descr;
}
@@ -1280,7 +1281,9 @@ PyArray_DiscoverDTypeAndShape(
}
if (requested_descr != NULL) {
- assert(fixed_DType == NPY_DTYPE(requested_descr));
+ if (fixed_DType != NULL) {
+ assert(fixed_DType == NPY_DTYPE(requested_descr));
+ }
/* The output descriptor must be the input. */
Py_INCREF(requested_descr);
*out_descr = requested_descr;
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 38af60427..84d6e80af 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -1605,6 +1605,37 @@ NPY_NO_EXPORT PyObject *
PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
int max_depth, int flags, PyObject *context)
{
+ npy_dtype_info dt_info = {NULL, NULL};
+
+ int res = PyArray_ExtractDTypeAndDescriptor(
+ newtype, &dt_info.descr, &dt_info.dtype);
+
+ Py_XDECREF(newtype);
+
+ if (res < 0) {
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
+ return NULL;
+ }
+
+ PyObject* ret = PyArray_FromAny_int(op, dt_info.descr, dt_info.dtype,
+ min_depth, max_depth, flags, context);
+
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
+ return ret;
+}
+
+/*
+ * Internal version of PyArray_FromAny that accepts a dtypemeta. Borrows
+ * references to the descriptor and dtype.
+ */
+
+NPY_NO_EXPORT PyObject *
+PyArray_FromAny_int(PyObject *op, PyArray_Descr *in_descr,
+ PyArray_DTypeMeta *in_DType, int min_depth, int max_depth,
+ int flags, PyObject *context)
+{
/*
* This is the main code to make a NumPy array from a Python
* Object. It is called from many different places.
@@ -1620,26 +1651,15 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
return NULL;
}
- PyArray_Descr *fixed_descriptor;
- PyArray_DTypeMeta *fixed_DType;
- if (PyArray_ExtractDTypeAndDescriptor(newtype,
- &fixed_descriptor, &fixed_DType) < 0) {
- Py_XDECREF(newtype);
- return NULL;
- }
- Py_XDECREF(newtype);
-
ndim = PyArray_DiscoverDTypeAndShape(op,
- NPY_MAXDIMS, dims, &cache, fixed_DType, fixed_descriptor, &dtype,
+ NPY_MAXDIMS, dims, &cache, in_DType, in_descr, &dtype,
flags & NPY_ARRAY_ENSURENOCOPY);
- Py_XDECREF(fixed_descriptor);
- Py_XDECREF(fixed_DType);
if (ndim < 0) {
return NULL;
}
- if (NPY_UNLIKELY(fixed_descriptor != NULL && PyDataType_HASSUBARRAY(dtype))) {
+ if (NPY_UNLIKELY(in_descr != NULL && PyDataType_HASSUBARRAY(dtype))) {
/*
* When a subarray dtype was passed in, its dimensions are appended
* to the array dimension (causing a dimension mismatch).
@@ -1737,7 +1757,7 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
}
else if (cache == NULL && PyArray_IsScalar(op, Void) &&
!(((PyVoidScalarObject *)op)->flags & NPY_ARRAY_OWNDATA) &&
- newtype == NULL) {
+ ((in_descr == NULL) && (in_DType == NULL))) {
/*
* Special case, we return a *view* into void scalars, mainly to
* allow things similar to the "reversed" assignment:
@@ -1768,7 +1788,7 @@ PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
return NULL;
}
- if (cache == NULL && newtype != NULL &&
+ if (cache == NULL && in_descr != NULL &&
PyDataType_ISSIGNED(dtype) &&
PyArray_IsScalar(op, Generic)) {
assert(ndim == 0);
@@ -1909,24 +1929,57 @@ NPY_NO_EXPORT PyObject *
PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth,
int max_depth, int requires, PyObject *context)
{
+ npy_dtype_info dt_info = {NULL, NULL};
+
+ 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;
+ }
+
+ PyObject* ret = PyArray_CheckFromAny_int(
+ op, dt_info.descr, dt_info.dtype, min_depth, max_depth, requires,
+ context);
+
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
+ return ret;
+}
+
+/*
+ * Internal version of PyArray_CheckFromAny that accepts a dtypemeta. Borrows
+ * references to the descriptor and dtype.
+ */
+
+NPY_NO_EXPORT PyObject *
+PyArray_CheckFromAny_int(PyObject *op, PyArray_Descr *in_descr,
+ PyArray_DTypeMeta *in_DType, int min_depth,
+ int max_depth, int requires, PyObject *context)
+{
PyObject *obj;
if (requires & NPY_ARRAY_NOTSWAPPED) {
- if (!descr && PyArray_Check(op) &&
+ if (!in_descr && PyArray_Check(op) &&
PyArray_ISBYTESWAPPED((PyArrayObject* )op)) {
- descr = PyArray_DescrNew(PyArray_DESCR((PyArrayObject *)op));
- if (descr == NULL) {
+ in_descr = PyArray_DescrNew(PyArray_DESCR((PyArrayObject *)op));
+ if (in_descr == NULL) {
return NULL;
}
}
- else if (descr && !PyArray_ISNBO(descr->byteorder)) {
- PyArray_DESCR_REPLACE(descr);
+ else if (in_descr && !PyArray_ISNBO(in_descr->byteorder)) {
+ PyArray_DESCR_REPLACE(in_descr);
}
- if (descr && descr->byteorder != NPY_IGNORE) {
- descr->byteorder = NPY_NATIVE;
+ if (in_descr && in_descr->byteorder != NPY_IGNORE) {
+ in_descr->byteorder = NPY_NATIVE;
}
}
- obj = PyArray_FromAny(op, descr, min_depth, max_depth, requires, context);
+ obj = PyArray_FromAny_int(op, in_descr, in_DType, min_depth,
+ max_depth, requires, context);
if (obj == NULL) {
return NULL;
}
diff --git a/numpy/core/src/multiarray/ctors.h b/numpy/core/src/multiarray/ctors.h
index 98160b1cc..22020e26a 100644
--- a/numpy/core/src/multiarray/ctors.h
+++ b/numpy/core/src/multiarray/ctors.h
@@ -36,10 +36,20 @@ _array_from_array_like(PyObject *op,
int never_copy);
NPY_NO_EXPORT PyObject *
+PyArray_FromAny_int(PyObject *op, PyArray_Descr *in_descr,
+ PyArray_DTypeMeta *in_DType, int min_depth, int max_depth,
+ int flags, PyObject *context);
+
+NPY_NO_EXPORT PyObject *
PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth,
int max_depth, int flags, PyObject *context);
NPY_NO_EXPORT PyObject *
+PyArray_CheckFromAny_int(PyObject *op, PyArray_Descr *in_descr,
+ PyArray_DTypeMeta *in_DType, int min_depth,
+ int max_depth, int requires, PyObject *context);
+
+NPY_NO_EXPORT PyObject *
PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth,
int max_depth, int requires, PyObject *context);
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index ac8e641b7..adc1558da 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -1635,25 +1635,35 @@ _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)))
+
static inline PyObject *
_array_fromobject_generic(
- PyObject *op, PyArray_Descr *type, _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;
int nd, flags = 0;
+ /* Hold on to `in_descr` as `dtype`, since we may also set it below. */
+ Py_XINCREF(in_descr);
+ PyArray_Descr *dtype = in_descr;
+
if (ndmin > NPY_MAXDIMS) {
PyErr_Format(PyExc_ValueError,
"ndmin bigger than allowable number of dimensions "
"NPY_MAXDIMS (=%d)", NPY_MAXDIMS);
- return NULL;
+ goto finish;
}
/* fast exit if simple call */
if (PyArray_CheckExact(op) || (subok && PyArray_Check(op))) {
oparr = (PyArrayObject *)op;
- if (type == NULL) {
+
+ if (dtype == NULL && in_DType == NULL) {
+ /*
+ * User did not ask for a specific dtype instance or class. So
+ * we can return either self or a copy.
+ */
if (copy != NPY_COPY_ALWAYS && STRIDING_OK(oparr, order)) {
ret = oparr;
Py_INCREF(ret);
@@ -1663,17 +1673,30 @@ _array_fromobject_generic(
if (copy == NPY_COPY_NEVER) {
PyErr_SetString(PyExc_ValueError,
"Unable to avoid copy while creating a new array.");
- return NULL;
+ goto finish;
}
ret = (PyArrayObject *)PyArray_NewCopy(oparr, order);
goto finish;
}
}
+ else if (dtype == NULL) {
+ /*
+ * If the user passed a DType class but not a dtype instance,
+ * we must use `PyArray_AdaptDescriptorToArray` to find the
+ * correct dtype instance.
+ * Even if the fast-path doesn't work we will use this.
+ */
+ dtype = PyArray_AdaptDescriptorToArray(oparr, in_DType, NULL);
+ if (dtype == NULL) {
+ goto finish;
+ }
+ }
+
/* One more chance for faster exit if user specified the dtype. */
oldtype = PyArray_DESCR(oparr);
- if (PyArray_EquivTypes(oldtype, type)) {
+ if (PyArray_EquivTypes(oldtype, dtype)) {
if (copy != NPY_COPY_ALWAYS && STRIDING_OK(oparr, order)) {
- if (oldtype == type) {
+ if (oldtype == dtype) {
Py_INCREF(op);
ret = oparr;
}
@@ -1681,10 +1704,10 @@ _array_fromobject_generic(
/* Create a new PyArrayObject from the caller's
* PyArray_Descr. Use the reference `op` as the base
* object. */
- Py_INCREF(type);
+ Py_INCREF(dtype);
ret = (PyArrayObject *)PyArray_NewFromDescrAndBase(
Py_TYPE(op),
- type,
+ dtype,
PyArray_NDIM(oparr),
PyArray_DIMS(oparr),
PyArray_STRIDES(oparr),
@@ -1700,10 +1723,10 @@ _array_fromobject_generic(
if (copy == NPY_COPY_NEVER) {
PyErr_SetString(PyExc_ValueError,
"Unable to avoid copy while creating a new array.");
- return NULL;
+ goto finish;
}
ret = (PyArrayObject *)PyArray_NewCopy(oparr, order);
- if (oldtype == type || ret == NULL) {
+ if (oldtype == dtype || ret == NULL) {
goto finish;
}
Py_INCREF(oldtype);
@@ -1734,11 +1757,13 @@ _array_fromobject_generic(
}
flags |= NPY_ARRAY_FORCECAST;
- Py_XINCREF(type);
- ret = (PyArrayObject *)PyArray_CheckFromAny(op, type,
- 0, 0, flags, NULL);
+
+ ret = (PyArrayObject *)PyArray_CheckFromAny_int(
+ op, dtype, in_DType, 0, 0, flags, NULL);
finish:
+ Py_XDECREF(dtype);
+
if (ret == NULL) {
return NULL;
}
@@ -1765,7 +1790,7 @@ array_array(PyObject *NPY_UNUSED(ignored),
npy_bool subok = NPY_FALSE;
_PyArray_CopyMode copy = NPY_COPY_ALWAYS;
int ndmin = 0;
- PyArray_Descr *type = NULL;
+ npy_dtype_info dt_info = {NULL, NULL};
NPY_ORDER order = NPY_KEEPORDER;
PyObject *like = Py_None;
NPY_PREPARE_ARGPARSER;
@@ -1773,21 +1798,23 @@ array_array(PyObject *NPY_UNUSED(ignored),
if (len_args != 1 || (kwnames != NULL)) {
if (npy_parse_arguments("array", args, len_args, kwnames,
"object", NULL, &op,
- "|dtype", &PyArray_DescrConverter2, &type,
+ "|dtype", &PyArray_DTypeOrDescrConverterOptional, &dt_info,
"$copy", &PyArray_CopyConverter, &copy,
"$order", &PyArray_OrderConverter, &order,
"$subok", &PyArray_BoolConverter, &subok,
"$ndmin", &PyArray_PythonPyIntFromInt, &ndmin,
"$like", NULL, &like,
NULL, NULL, NULL) < 0) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return NULL;
}
if (like != Py_None) {
PyObject *deferred = array_implement_c_array_function_creation(
"array", like, NULL, NULL, args, len_args, kwnames);
if (deferred != Py_NotImplemented) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return deferred;
}
}
@@ -1798,8 +1825,9 @@ array_array(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, type, copy, order, subok, ndmin);
- Py_XDECREF(type);
+ op, dt_info.descr, dt_info.dtype, copy, order, subok, ndmin);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return res;
}
@@ -1808,7 +1836,7 @@ array_asarray(PyObject *NPY_UNUSED(ignored),
PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *op;
- PyArray_Descr *type = NULL;
+ npy_dtype_info dt_info = {NULL, NULL};
NPY_ORDER order = NPY_KEEPORDER;
PyObject *like = Py_None;
NPY_PREPARE_ARGPARSER;
@@ -1816,18 +1844,20 @@ array_asarray(PyObject *NPY_UNUSED(ignored),
if (len_args != 1 || (kwnames != NULL)) {
if (npy_parse_arguments("asarray", args, len_args, kwnames,
"a", NULL, &op,
- "|dtype", &PyArray_DescrConverter2, &type,
+ "|dtype", &PyArray_DTypeOrDescrConverterOptional, &dt_info,
"|order", &PyArray_OrderConverter, &order,
"$like", NULL, &like,
NULL, NULL, NULL) < 0) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return NULL;
}
if (like != Py_None) {
PyObject *deferred = array_implement_c_array_function_creation(
"asarray", like, NULL, NULL, args, len_args, kwnames);
if (deferred != Py_NotImplemented) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return deferred;
}
}
@@ -1837,8 +1867,9 @@ array_asarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, type, NPY_FALSE, order, NPY_FALSE, 0);
- Py_XDECREF(type);
+ 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;
}
@@ -1847,7 +1878,7 @@ array_asanyarray(PyObject *NPY_UNUSED(ignored),
PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *op;
- PyArray_Descr *type = NULL;
+ npy_dtype_info dt_info = {NULL, NULL};
NPY_ORDER order = NPY_KEEPORDER;
PyObject *like = Py_None;
NPY_PREPARE_ARGPARSER;
@@ -1855,18 +1886,20 @@ array_asanyarray(PyObject *NPY_UNUSED(ignored),
if (len_args != 1 || (kwnames != NULL)) {
if (npy_parse_arguments("asanyarray", args, len_args, kwnames,
"a", NULL, &op,
- "|dtype", &PyArray_DescrConverter2, &type,
+ "|dtype", &PyArray_DTypeOrDescrConverterOptional, &dt_info,
"|order", &PyArray_OrderConverter, &order,
"$like", NULL, &like,
NULL, NULL, NULL) < 0) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return NULL;
}
if (like != Py_None) {
PyObject *deferred = array_implement_c_array_function_creation(
"asanyarray", like, NULL, NULL, args, len_args, kwnames);
if (deferred != Py_NotImplemented) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return deferred;
}
}
@@ -1876,8 +1909,9 @@ array_asanyarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, type, NPY_FALSE, order, NPY_TRUE, 0);
- Py_XDECREF(type);
+ 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;
}
@@ -1887,24 +1921,26 @@ array_ascontiguousarray(PyObject *NPY_UNUSED(ignored),
PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *op;
- PyArray_Descr *type = NULL;
+ npy_dtype_info dt_info = {NULL, NULL};
PyObject *like = Py_None;
NPY_PREPARE_ARGPARSER;
if (len_args != 1 || (kwnames != NULL)) {
if (npy_parse_arguments("ascontiguousarray", args, len_args, kwnames,
"a", NULL, &op,
- "|dtype", &PyArray_DescrConverter2, &type,
+ "|dtype", &PyArray_DTypeOrDescrConverterOptional, &dt_info,
"$like", NULL, &like,
NULL, NULL, NULL) < 0) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return NULL;
}
if (like != Py_None) {
PyObject *deferred = array_implement_c_array_function_creation(
"ascontiguousarray", like, NULL, NULL, args, len_args, kwnames);
if (deferred != Py_NotImplemented) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return deferred;
}
}
@@ -1914,8 +1950,10 @@ array_ascontiguousarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, type, NPY_FALSE, NPY_CORDER, NPY_FALSE, 1);
- Py_XDECREF(type);
+ 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;
}
@@ -1925,24 +1963,26 @@ array_asfortranarray(PyObject *NPY_UNUSED(ignored),
PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *op;
- PyArray_Descr *type = NULL;
+ npy_dtype_info dt_info = {NULL, NULL};
PyObject *like = Py_None;
NPY_PREPARE_ARGPARSER;
if (len_args != 1 || (kwnames != NULL)) {
if (npy_parse_arguments("asfortranarray", args, len_args, kwnames,
"a", NULL, &op,
- "|dtype", &PyArray_DescrConverter2, &type,
+ "|dtype", &PyArray_DTypeOrDescrConverterOptional, &dt_info,
"$like", NULL, &like,
NULL, NULL, NULL) < 0) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return NULL;
}
if (like != Py_None) {
PyObject *deferred = array_implement_c_array_function_creation(
"asfortranarray", like, NULL, NULL, args, len_args, kwnames);
if (deferred != Py_NotImplemented) {
- Py_XDECREF(type);
+ Py_XDECREF(dt_info.descr);
+ Py_XDECREF(dt_info.dtype);
return deferred;
}
}
@@ -1952,8 +1992,10 @@ array_asfortranarray(PyObject *NPY_UNUSED(ignored),
}
PyObject *res = _array_fromobject_generic(
- op, type, NPY_FALSE, NPY_FORTRANORDER, NPY_FALSE, 1);
- Py_XDECREF(type);
+ 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;
}