diff options
author | Nathan Goldbaum <nathan.goldbaum@gmail.com> | 2023-03-17 13:11:19 -0600 |
---|---|---|
committer | Nathan Goldbaum <nathan.goldbaum@gmail.com> | 2023-03-17 13:11:19 -0600 |
commit | 5ae51e23587faa3bd58ed889fed9871f618d3ca1 (patch) | |
tree | 483136974f8196e23b7afc4e567d60e45e3f46ee | |
parent | 18e7fbd4301459a08432053ac992b02ece13273e (diff) | |
download | numpy-5ae51e23587faa3bd58ed889fed9871f618d3ca1.tar.gz |
MAINT: avoid calling PyArray_AdaptDescriptorToArray in some cases
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index f0b3a0e13..37c7f14bd 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -1653,10 +1653,32 @@ _array_fromobject_generic( /* fast exit if simple call */ if (PyArray_CheckExact(op) || (subok && PyArray_Check(op))) { oparr = (PyArrayObject *)op; - PyArray_Descr* dtype = PyArray_AdaptDescriptorToArray( - oparr, dt_info.dtype, dt_info.descr); - if (dtype == NULL) { - return NULL; + PyArray_Descr* dtype = NULL; + /* + * 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: + * + * >>> 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))) { + dtype = PyArray_AdaptDescriptorToArray( + oparr, dt_info.dtype, dt_info.descr); + if (dtype == NULL) { + return NULL; + } + } + else { + if ((dt_info.descr == NULL) && (dt_info.dtype == NULL)) { + dtype = PyArray_DESCR(oparr); + } + else { + dtype = dt_info.descr; + } + Py_INCREF(dtype); } if ((dt_info.descr == NULL) && (dt_info.dtype == NULL)) { if (copy != NPY_COPY_ALWAYS && STRIDING_OK(oparr, order)) { |