@@ -523,7 +523,7 @@ prepare_index(PyArrayObject *self, PyObject *index,
523523 "in the future, boolean array-likes will be "
524524 "handled as a boolean array index" ) < 0 ) {
525525 Py_DECREF (tmp_arr );
526- goto failed_building_indices ;
526+ goto failed_building_indices ;
527527 }
528528 if (PyArray_NDIM (tmp_arr ) == 0 ) {
529529 /*
@@ -562,7 +562,7 @@ prepare_index(PyArrayObject *self, PyObject *index,
562562 "numpy.newaxis (`None`) and integer or boolean "
563563 "arrays are valid indices" );
564564 Py_DECREF ((PyObject * )tmp_arr );
565- goto failed_building_indices ;
565+ goto failed_building_indices ;
566566 }
567567 }
568568 else {
@@ -576,9 +576,9 @@ prepare_index(PyArrayObject *self, PyObject *index,
576576 "non integer (and non boolean) array-likes will "
577577 "not be accepted as indices in the future" );
578578 Py_DECREF ((PyObject * )tmp_arr );
579- goto failed_building_indices ;
579+ goto failed_building_indices ;
580580 }
581- }
581+ }
582582 }
583583
584584 PyArray_Descr * indtype = PyArray_DescrFromType (NPY_INTP );
@@ -984,8 +984,8 @@ array_boolean_subscript(PyArrayObject *self,
984984 /* Allocate the output of the boolean indexing */
985985 dtype = PyArray_DESCR (self );
986986 Py_INCREF (dtype );
987- ret = (PyArrayObject * )PyArray_NewFromDescr (Py_TYPE ( self ) , dtype , 1 , & size ,
988- NULL , NULL , 0 , ( PyObject * ) self );
987+ ret = (PyArrayObject * )PyArray_NewFromDescr (& PyArray_Type , dtype , 1 , & size ,
988+ NULL , NULL , 0 , NULL );
989989 if (ret == NULL ) {
990990 return NULL ;
991991 }
@@ -1074,6 +1074,24 @@ array_boolean_subscript(PyArrayObject *self,
10741074 NPY_AUXDATA_FREE (transferdata );
10751075 }
10761076
1077+ if (!PyArray_CheckExact (self )) {
1078+ PyArrayObject * tmp = ret ;
1079+
1080+ ret = (PyArrayObject * )PyArray_NewFromDescr (Py_TYPE (self ), dtype , 1 ,
1081+ & size , PyArray_STRIDES (ret ), PyArray_BYTES (ret ),
1082+ 0 , (PyObject * )self );
1083+
1084+ if (ret == NULL ) {
1085+ Py_DECREF (tmp );
1086+ return NULL ;
1087+ }
1088+
1089+ if (PyArray_SetBaseObject (ret , tmp ) < 0 ) {
1090+ Py_DECREF (ret );
1091+ return NULL ;
1092+ }
1093+ }
1094+
10771095 return ret ;
10781096}
10791097
@@ -1511,10 +1529,11 @@ array_subscript(PyArrayObject *self, PyObject *op)
15111529 Py_DECREF (tmp_arr );
15121530 goto finish ;
15131531 }
1514- /* TODO: Could attempt to steal the data from the old result */
1532+
15151533 if (PyArray_SetBaseObject ((PyArrayObject * )result ,
15161534 (PyObject * )tmp_arr ) < 0 ) {
1517- Py_DECREF (tmp_arr );
1535+ Py_DECREF (result );
1536+ result = NULL ;
15181537 goto finish ;
15191538 }
15201539 }
@@ -1686,25 +1705,20 @@ array_ass_sub(PyArrayObject *self, PyObject *ind, PyObject *op)
16861705
16871706 /* If there is no fancy indexing, we have the array to assign to */
16881707 if (!(index_type & HAS_FANCY )) {
1689- /*
1690- * CopyObject handles all weirdness for us, this however also
1691- * means that other array assignments which convert more strictly
1692- * do *not* handle all weirdnesses correctly.
1693- * TODO: To have other assignments handle them correctly, we
1694- * should copy into a temporary array of the correct shape
1695- * if it is not an array yet!
1696- * TODO: We could use PyArray_SETITEM if it is 0-d?
1697- */
16981708 if (PyArray_CopyObject (view , op ) < 0 ) {
16991709 goto fail ;
17001710 }
17011711 goto success ;
17021712 }
17031713
17041714 if (!PyArray_Check (op )) {
1705- if ((PyDataType_HASFIELDS (descr ) || PyDataType_REFCHK (descr ))
1706- && PySequence_Check (op )) {
1707- /* Allocate array through MapIter to fill with CopyObject */
1715+ /*
1716+ * If the array is of object converting the values to an array
1717+ * might not be legal even though normal assignment works.
1718+ * So allocate a temporary array of the right size and use the
1719+ * normal assignment to handle this case.
1720+ */
1721+ if (PyDataType_REFCHK (descr ) && PySequence_Check (op )) {
17081722 tmp_arr = NULL ;
17091723 }
17101724 else {
@@ -2446,17 +2460,16 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
24462460 * 2. Subspace iteration is necessary, so the extra op is iterated
24472461 * independendly, and the iteration order is fixed at C (could
24482462 * also use Fortran order if the array is Fortran order).
2449- * In this case the subspace iterator is buffered, so that even
2450- * the array being iterated *is* buffered!
2463+ * In this case the subspace iterator is not buffered.
24512464 * 3. Subspace iteration is necessary and an extra_op was given.
2452- * In this case it needs to be transposed!
2465+ * In this case it may need transposing, etc.
24532466 */
24542467
24552468 /*
24562469 * If we have an extra_op given, need to prepare it.
24572470 * 1. Subclasses might mess with the shape, so need a baseclass
24582471 * 2. Need to make sure the shape is compatible
2459- * 3. May need to transpose it .
2472+ * 3. May need to remove leading 1s and transpose dimensions .
24602473 */
24612474 if (extra_op != NULL ) {
24622475 if (!PyArray_CheckExact (extra_op )) {
@@ -2471,10 +2484,9 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
24712484
24722485 if (PyArray_NDIM (extra_op ) > mit -> nd ) {
24732486 /*
2474- * Usual assignments allows removal of trailing one dimensions.
2487+ * Usual assignments allows removal of leading one dimensions.
24752488 * (or equivalently adding of one dimensions to the array being
2476- * assigned to). To implement this, reshape the array. It is a bit
2477- * of a hack.
2489+ * assigned to). To implement this, reshape the array.
24782490 * This should maybe be done differently, or even not be allowed.
24792491 */
24802492 PyArrayObject * tmp_arr ;
0 commit comments