@@ -1655,6 +1655,58 @@ array_assign_item(PyArrayObject *self, Py_ssize_t i, PyObject *op)
1655
1655
}
1656
1656
1657
1657
1658
+ /*
1659
+ * This fallback takes the old route of `arr.flat[index] = values`
1660
+ * for one dimensional `arr`. The route can sometimes fail slightly
1661
+ * different (ValueError instead of IndexError), in which case we
1662
+ * warn users about the change. But since it does not actually care *at all*
1663
+ * about shapes, it should only fail for out of bound indexes or
1664
+ * casting errors.
1665
+ */
1666
+ NPY_NO_EXPORT int
1667
+ attempt_1d_fallback (PyArrayObject * self , PyObject * ind , PyObject * op )
1668
+ {
1669
+ PyObject * err = PyErr_Occurred ();
1670
+ PyArrayIterObject * self_iter = NULL ;
1671
+
1672
+ Py_INCREF (err );
1673
+ PyErr_Clear ();
1674
+
1675
+ self_iter = (PyArrayIterObject * )PyArray_IterNew ((PyObject * )self );
1676
+ if (self_iter == NULL ) {
1677
+ goto fail ;
1678
+ }
1679
+ if (iter_ass_subscript (self_iter , ind , op ) < 0 ) {
1680
+ goto fail ;
1681
+ }
1682
+
1683
+ Py_XDECREF ((PyObject * )self_iter );
1684
+ Py_DECREF (err );
1685
+
1686
+ if (DEPRECATE (
1687
+ "assignment will raise an error in the future, most likely "
1688
+ "because your index result shape does not match the value array "
1689
+ "shape. You can use `arr.flat[index] = values` to keep the old "
1690
+ "behaviour." ) < 0 ) {
1691
+ return -1 ;
1692
+ }
1693
+ return 0 ;
1694
+
1695
+ fail :
1696
+ if (!PyErr_ExceptionMatches (err )) {
1697
+ PyObject * err , * val , * tb ;
1698
+ PyErr_Fetch (& err , & val , & tb );
1699
+ DEPRECATE_FUTUREWARNING (
1700
+ "assignment exception type will change in the future" );
1701
+ PyErr_Restore (err , val , tb );
1702
+ }
1703
+
1704
+ Py_XDECREF ((PyObject * )self_iter );
1705
+ Py_DECREF (err );
1706
+ return -1 ;
1707
+ }
1708
+
1709
+
1658
1710
/*
1659
1711
* General assignment with python indexing objects.
1660
1712
*/
@@ -1746,9 +1798,20 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op)
1746
1798
Py_INCREF (op );
1747
1799
tmp_arr = (PyArrayObject * )op ;
1748
1800
}
1801
+
1749
1802
if (array_assign_boolean_subscript (self ,
1750
1803
(PyArrayObject * )indices [0 ].object ,
1751
1804
tmp_arr , NPY_CORDER ) < 0 ) {
1805
+ /*
1806
+ * Deprecated case. The old boolean indexing seemed to have some
1807
+ * check to allow wrong dimensional boolean arrays in all cases.
1808
+ */
1809
+ if (PyArray_NDIM (tmp_arr ) > 1 ) {
1810
+ if (attempt_1d_fallback (self , indices [0 ].object , tmp_arr ) < 0 ) {
1811
+ goto fail ;
1812
+ }
1813
+ goto success ;
1814
+ }
1752
1815
goto fail ;
1753
1816
}
1754
1817
goto success ;
@@ -1899,14 +1962,36 @@ array_assign_subscript(PyArrayObject *self, PyObject *ind, PyObject *op)
1899
1962
tmp_arr , descr );
1900
1963
1901
1964
if (mit == NULL ) {
1902
- goto fail ;
1965
+ /*
1966
+ * This is a deprecated special case to allow non-matching shapes
1967
+ * for the index and value arrays.
1968
+ */
1969
+ if (index_type != HAS_FANCY || index_num != 1 ) {
1970
+ /* This is not a "flat like" 1-d special case */
1971
+ goto fail ;
1972
+ }
1973
+ if (attempt_1d_fallback (self , indices [0 ].object , op ) < 0 ) {
1974
+ goto fail ;
1975
+ }
1976
+ goto success ;
1903
1977
}
1904
1978
1905
1979
if (tmp_arr == NULL ) {
1906
1980
/* Fill extra op */
1907
1981
1908
1982
if (PyArray_CopyObject (mit -> extra_op , op ) < 0 ) {
1909
- goto fail ;
1983
+ /*
1984
+ * This is a deprecated special case to allow non-matching shapes
1985
+ * for the index and value arrays.
1986
+ */
1987
+ if (index_type != HAS_FANCY || index_num != 1 ) {
1988
+ /* This is not a "flat like" 1-d special case */
1989
+ goto fail ;
1990
+ }
1991
+ if (attempt_1d_fallback (self , indices [0 ].object , op ) < 0 ) {
1992
+ goto fail ;
1993
+ }
1994
+ goto success ;
1910
1995
}
1911
1996
}
1912
1997
0 commit comments