diff -r 8002f45377d4 Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Sat Mar 16 15:39:42 2013 -0700 +++ b/Modules/itertoolsmodule.c Tue Mar 19 01:42:05 2013 +0100 @@ -1515,6 +1515,77 @@ return item; } +PyDoc_STRVAR(islice_send_doc, "send object into the inner iterator, " + "skipping items as necessary."); + +static PyObject * +islice_send(PyObject *self, PyObject *args) +{ + isliceobject *lz = (isliceobject *)self; + PyObject *item; + Py_ssize_t stop = lz->stop; + Py_ssize_t oldnext; + _Py_IDENTIFIER(send); + PyObject *send_method = _PyObject_GetAttrId(lz->it, &PyId_send); + + while (lz->cnt < lz->next) { + item = PyObject_CallFunction(send_method, "O", Py_None); + if (item == NULL) + return NULL; + Py_DECREF(item); + lz->cnt++; + } + if (stop != -1 && lz->cnt >= stop) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + item = PyObject_Call(send_method, args, NULL); + if (item == NULL) + return NULL; + lz->cnt++; + oldnext = lz->next; + /* The (size_t) cast below avoids the danger of undefined + behaviour from signed integer overflow. */ + lz->next += (size_t)lz->step; + if (lz->next < oldnext || (stop != -1 && lz->next > stop)) + lz->next = stop; + return item; +} + + +PyDoc_STRVAR(islice_throw_doc, "throw exception into the inner iterator, "); + +static PyObject * +islice_throw(PyObject *self, PyObject *args) +{ + isliceobject *lz = (isliceobject *)self; + PyObject *item; + Py_ssize_t stop = lz->stop; + Py_ssize_t oldnext; + _Py_IDENTIFIER(throw); + PyObject *throw_method; + + if (stop != -1 && lz->cnt >= stop) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + throw_method = _PyObject_GetAttrId(lz->it, &PyId_throw); + if (throw_method == NULL) + return NULL; + item = PyObject_CallObject(throw_method, args); + Py_DECREF(throw_method); + if (item == NULL) + return NULL; + lz->cnt++; + oldnext = lz->next; + /* The (size_t) cast below avoids the danger of undefined + behaviour from signed integer overflow. */ + lz->next += (size_t)lz->step; + if (lz->next < oldnext || (stop != -1 && lz->next > stop)) + lz->next = stop; + return item; +} + static PyObject * islice_reduce(isliceobject *lz) { @@ -1550,6 +1621,10 @@ reduce_doc}, {"__setstate__", (PyCFunction)islice_setstate, METH_O, setstate_doc}, + {"send", (PyCFunction)islice_send, METH_VARARGS, + islice_send_doc}, + {"throw", (PyCFunction)islice_throw, METH_VARARGS, + islice_throw_doc}, {NULL, NULL} /* sentinel */ };