@@ -578,6 +578,7 @@ PyArray_Concatenate(PyObject *op, int axis)
578
578
int iarrays , narrays ;
579
579
PyArrayObject * * arrays ;
580
580
PyArrayObject * ret ;
581
+ PyArray_Descr * dtype = NULL ;
581
582
582
583
if (!PySequence_Check (op )) {
583
584
PyErr_SetString (PyExc_TypeError ,
@@ -597,17 +598,75 @@ PyArray_Concatenate(PyObject *op, int axis)
597
598
}
598
599
for (iarrays = 0 ; iarrays < narrays ; ++ iarrays ) {
599
600
PyObject * item = PySequence_GetItem (op , iarrays );
601
+ PyArrayObject * arr ;
602
+
600
603
if (item == NULL ) {
601
604
narrays = iarrays ;
602
605
goto fail ;
603
606
}
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 );
606
665
Py_DECREF (item );
607
- if (arrays [iarrays ] == NULL ) {
608
- narrays = iarrays ;
666
+ if (arr == NULL ) {
609
667
goto fail ;
610
668
}
669
+ arrays [iarrays ++ ] = arr ;
611
670
}
612
671
613
672
if (axis >= NPY_MAXDIMS ) {
@@ -627,7 +686,7 @@ PyArray_Concatenate(PyObject *op, int axis)
627
686
fail :
628
687
/* 'narrays' was set to how far we got in the conversion */
629
688
for (iarrays = 0 ; iarrays < narrays ; ++ iarrays ) {
630
- Py_DECREF (arrays [iarrays ]);
689
+ Py_XDECREF (arrays [iarrays ]);
631
690
}
632
691
PyArray_free (arrays );
633
692
0 commit comments