8000 BUG: Concatenate with empty sequences, fixes #1586 · numpy/numpy@7d1f87a · GitHub
[go: up one dir, main page]

Skip to content

Commit 7d1f87a

Browse files
committed
BUG: Concatenate with empty sequences, fixes #1586
1 parent 6078824 commit 7d1f87a

File tree

1 file changed

+64
-5
lines changed

1 file changed

+64
-5
lines changed

numpy/core/src/multiarray/multiarraymodule.c

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ PyArray_Concatenate(PyObject *op, int axis)
578578
int iarrays, narrays;
579579
PyArrayObject **arrays;
580580
PyArrayObject *ret;
581+
PyArray_Descr *dtype = NULL;
581582

582583
if (!PySequence_Check(op)) {
583584
PyErr_SetString(PyExc_TypeError,
@@ -597,17 +598,75 @@ PyArray_Concatenate(PyObject *op, int axis)
597598
}
598599
for (iarrays = 0; iarrays < narrays; ++iarrays) {
599600
PyObject *item = PySequence_GetItem(op, iarrays);
601+
PyArrayObject *arr;
602+
600603
if (item == NULL) {
601604
narrays = iarrays;
602605
goto fail;
603606
}
604-
arrays[iarrays] = (PyArrayObject *)PyArray_FromAny(item, NULL,
605-
0, 0, 0, NULL);
607+
if (PyArray_Check(item)) {
608+
/* If it is already an array, we steal item's reference */
609+
arr = (PyArrayObject *)item;
610+
dtype = PyArray_DESCR(arr);
611+
}
612+
else {
613+
arr = (PyArrayObject *)PyArray_FromAny(item, NULL, 0, 0, 0, NULL);
614+
Py_DECREF(item);
615+
if (arr == NULL) {
616+
narrays = iarrays;
617+
goto fail;
618+
}
619+
if (PyArray_SIZE(arr) == 0) {
620+
/*
621+
* Item was not an array and is empty, so we need to
622+
* cast it to a known dtype in op, or delay creation
623+
* until after we have found a non-default dtype.
624+
*/
625+
if (dtype == NULL) {
626+
Py_DECREF(arr);
627+
arr = NULL;
628+
}
629+
else {
630+
PyArrayObject *temp;
631+
632+
Py_INCREF(dtype);
633+
temp = (PyArrayObject *)PyArray_FromArray(arr, dtype,
634+
NPY_ARRAY_FORCECAST);
635+
Py_DECREF(arr);
636+
if (temp == NULL) {
637+
narrays = iarrays;
638+
goto fail;
639+
}
640+
arr = temp;
641+
}
642+
}
643+
else {
644+
dtype = PyArray_DESCR(arr);
645+
}
646+
}
647+
arrays[iarrays] = arr;
648+
}
649+
/*
650+
* Leading non-array empty items in op have not been converted to
651+
* arrays for lack of a non-default dtype, convert them now. Notice
652+
* that dtype may still be NULL, in which case we end up with the
653+
* default dtype we tried so hard to avoid.
654+
*/
655+
iarrays = 0;
656+
while (iarrays < narrays && arrays[iarrays] == NULL) {
657+
PyObject *item = PySequence_GetItem(op, iarrays);
658+
PyArrayObject *arr;
659+
660+
if (item == NULL) {
661+
goto fail;
662+
}
663+
Py_XINCREF(dtype);
664+
arr = (PyArrayObject *)PyArray_FromAny(item, dtype, 0, 0, 0, NULL);
606665
Py_DECREF(item);
607-
if (arrays[iarrays] == NULL) {
608-
narrays = iarrays;
666+
if (arr == NULL) {
609667
goto fail;
610668
}
669+
arrays[iarrays++] = arr;
611670
}
612671

613672
if (axis >= NPY_MAXDIMS) {
@@ -627,7 +686,7 @@ PyArray_Concatenate(PyObject *op, int axis)
627686
fail:
628687
/* 'narrays' was set to how far we got in the conversion */
629688
for (iarrays = 0; iarrays < narrays; ++iarrays) {
630-
Py_DECREF(arrays[iarrays]);
689+
Py_XDECREF(arrays[iarrays]);
631690
}
632691
PyArray_free(arrays);
633692

0 commit comments

Comments
 (0)
0