@@ -1660,6 +1660,35 @@ islice_next(PyObject *op)
16601660 return NULL ;
16611661}
16621662
1663+ static PyObject *
1664+ islice_length_hint (PyObject * op , PyObject * Py_UNUSED (dummy ))
1665+ {
1666+ isliceobject * lz = isliceobject_CAST (op );
1667+
1668+ if (lz -> stop >= 0 && lz -> stop <= lz -> next ) {
1669+ return PyLong_FromSsize_t (0 );
1670+ }
1671+
1672+ Py_ssize_t remaining ;
1673+ if (lz -> stop == -1 ) {
1674+ Py_ssize_t hint = PyObject_LengthHint (lz -> it , 0 );
1675+ if (hint < 0 ) {
1676+ /* propagate exception */
1677+ return NULL ;
1678+ }
1679+ remaining = hint - lz -> next ;
1680+ } else {
1681+ remaining = lz -> stop - lz -> next ;
1682+ }
1683+
1684+ if (remaining <= 0 ) {
1685+ return PyLong_FromSsize_t (0 );
1686+ }
1687+
1688+ Py_ssize_t steps = (remaining + lz -> step - 1 ) / lz -> step ;
1689+ return PyLong_FromSsize_t (steps );
1690+ }
1691+
16631692PyDoc_STRVAR (islice_doc ,
16641693"islice(iterable, stop) --> islice object\n\
16651694islice(iterable, start, stop[, step]) --> islice object\n\
@@ -1671,6 +1700,11 @@ specified as another value, step determines how many values are\n\
16711700skipped between successive calls. Works like a slice() on a list\n\
16721701but returns an iterator." );
16731702
1703+ static PyMethodDef islice_methods [] = {
1704+ {"__length_hint__" , islice_length_hint , METH_NOARGS , NULL },
1705+ {NULL , NULL },
1706+ };
1707+
16741708static PyType_Slot islice_slots [] = {
16751709 {Py_tp_dealloc , islice_dealloc },
16761710 {Py_tp_getattro , PyObject_GenericGetAttr },
@@ -1680,6 +1714,7 @@ static PyType_Slot islice_slots[] = {
16801714 {Py_tp_iternext , islice_next },
16811715 {Py_tp_new , islice_new },
16821716 {Py_tp_free , PyObject_GC_Del },
1717+ {Py_tp_methods , islice_methods },
16831718 {0 , NULL },
16841719};
16851720
0 commit comments