@@ -1801,13 +1801,14 @@ element_subscr(PyObject *op, PyObject *item)
18011801 if (i == -1 && PyErr_Occurred ()) {
18021802 return NULL ;
18031803 }
1804- // If PyNumber_AsSsize_t() clears 'self->extra',
1805- // we want element_getitem() to raise IndexError.
18061804 if (i < 0 && self -> extra )
18071805 i += self -> extra -> length ;
18081806 return element_getitem (op , i );
18091807 }
18101808 else if (PySlice_Check (item )) {
1809+ // Note: 'slicelen' is computed once we are sure that 'self->extra'
1810+ // cannot be mutated by user-defined code.
1811+ // See https://github.com/python/cpython/issues/143200.
18111812 Py_ssize_t start , stop , step , slicelen , i ;
18121813 size_t cur ;
18131814 PyObject * list ;
@@ -1816,15 +1817,9 @@ element_subscr(PyObject *op, PyObject *item)
18161817 return NULL ;
18171818 }
18181819
1819- // Even if PySlice_Unpack() may clear 'self->extra',
1820- // using a slice should not raise an IndexError, so
1821- // we do not need to ensure 'extra' to exist.
1822- //
1823- // See https://github.com/python/cpython/issues/143200.
18241820 if (self -> extra == NULL ) {
18251821 return PyList_New (0 );
18261822 }
1827-
18281823 slicelen = PySlice_AdjustIndices (self -> extra -> length , & start , & stop ,
18291824 step );
18301825
@@ -1862,13 +1857,14 @@ element_ass_subscr(PyObject *op, PyObject *item, PyObject *value)
18621857 if (i == -1 && PyErr_Occurred ()) {
18631858 return -1 ;
18641859 }
1865- // If PyNumber_AsSsize_t() clears 'self->extra',
1866- // we want element_setitem() to raise IndexError.
18671860 if (i < 0 && self -> extra )
18681861 i += self -> extra -> length ;
18691862 return element_setitem (op , i , value );
18701863 }
18711864 else if (PySlice_Check (item )) {
1865+ // Note: 'slicelen' is computed once we are sure that 'self->extra'
1866+ // cannot be mutated by user-defined code.
1867+ // See https://github.com/python/cpython/issues/143200.
18721868 Py_ssize_t start , stop , step , slicelen , newlen , i ;
18731869 size_t cur ;
18741870
@@ -1878,23 +1874,22 @@ element_ass_subscr(PyObject *op, PyObject *item, PyObject *value)
18781874 if (PySlice_Unpack (item , & start , & stop , & step ) < 0 ) {
18791875 return -1 ;
18801876 }
1877+
18811878 // Since PySlice_Unpack() may clear 'self->extra', we need
18821879 // to ensure that it exists now (using a slice for assignment
18831880 // should not raise IndexError).
18841881 //
18851882 // See https://github.com/python/cpython/issues/143200.
1886- if (self -> extra == NULL && create_extra (self , NULL ) < 0 ) {
1887- return -1 ;
1883+ if (self -> extra == NULL ) {
1884+ if (create_extra (self , NULL ) < 0 ) {
1885+ return -1 ;
1886+ }
18881887 }
18891888
1890- slicelen = PySlice_AdjustIndices (self -> extra -> length , & start , & stop ,
1891- step );
1892-
18931889 if (value == NULL ) {
18941890 /* Delete slice */
1895- size_t cur ;
1896- Py_ssize_t i ;
1897-
1891+ slicelen = PySlice_AdjustIndices (self -> extra -> length , & start , & stop ,
1892+ step );
18981893 if (slicelen <= 0 )
18991894 return 0 ;
19001895
@@ -1965,20 +1960,16 @@ element_ass_subscr(PyObject *op, PyObject *item, PyObject *value)
19651960 }
19661961 newlen = PySequence_Fast_GET_SIZE (seq );
19671962
1968- // Re-create 'self->extra' if PySequence_Fast() cleared it.
1969- // See https://github.com/python/cpython/issues/143200.
19701963 if (self -> extra == NULL ) {
19711964 if (create_extra (self , NULL ) < 0 ) {
19721965 Py_DECREF (seq );
19731966 return -1 ;
19741967 }
1975- // re-compute the slice length since self->extra->length changed
1976- slicelen = PySlice_AdjustIndices (self -> extra -> length , & start , & stop ,
1977- step );
19781968 }
1969+ slicelen = PySlice_AdjustIndices (self -> extra -> length , & start , & stop ,
1970+ step );
19791971
1980- if (step != 1 && newlen != slicelen )
1981- {
1972+ if (step != 1 && newlen != slicelen ) {
19821973 Py_DECREF (seq );
19831974 PyErr_Format (PyExc_ValueError ,
19841975 "attempt to assign sequence of size %zd "
0 commit comments