diff -r 1043cc2cb0ff Lib/test/test_itertools.py --- a/Lib/test/test_itertools.py Sat Sep 07 15:24:01 2013 +0300 +++ b/Lib/test/test_itertools.py Sat Sep 07 18:27:42 2013 +0300 @@ -1104,6 +1104,18 @@ [1, 3, 5]) self.pickletest(takewhile(underten, data)) + # check .last + t = takewhile(underten, data) + self.assertEqual(t.last, None) + self.assertEqual(list(t), [1, 3, 5]) + self.assertEqual(t.last, 20) + + # check .last is None if no item failed + t = takewhile(underten, [1, 3, 5, 7]) + self.assertEqual(t.last, None) + self.assertEqual(list(t), [1, 3, 5, 7]) + self.assertEqual(t.last, None) + def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) diff -r 1043cc2cb0ff Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c Sat Sep 07 15:24:01 2013 +0300 +++ b/Modules/itertoolsmodule.c Sat Sep 07 18:27:42 2013 +0300 @@ -1216,6 +1216,7 @@ PyObject_HEAD PyObject *func; PyObject *it; + PyObject *last; long stop; } takewhileobject; @@ -1226,6 +1227,7 @@ { PyObject *func, *seq; PyObject *it; + PyObject *last; takewhileobject *lz; if (type == &takewhile_type && !_PyArg_NoKeywords("takewhile()", kwds)) @@ -1250,6 +1252,10 @@ lz->it = it; lz->stop = 0; + last = Py_None; + Py_INCREF(last); + lz->last = last; + return (PyObject *)lz; } @@ -1259,6 +1265,7 @@ PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); + Py_XDECREF(lz->last); Py_TYPE(lz)->tp_free(lz); } @@ -1267,6 +1274,7 @@ { Py_VISIT(lz->it); Py_VISIT(lz->func); + Py_VISIT(lz->last); return 0; } @@ -1293,9 +1301,12 @@ Py_DECREF(good); if (ok == 1) return item; + if (ok == 0) { + Py_INCREF(item); + lz->stop = 1; + lz->last = item; + } Py_DECREF(item); - if (ok == 0) - lz->stop = 1; return NULL; } @@ -1307,6 +1318,16 @@ } static PyObject * +takewhile_last_get(takewhileobject *lz) +{ + if(lz->last) { + Py_INCREF(lz->last); + return lz->last; + } + Py_RETURN_NONE; +} + +static PyObject * takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) { int stop = PyObject_IsTrue(state); @@ -1316,6 +1337,12 @@ Py_RETURN_NONE; } +static PyGetSetDef takewhile_getset[] = { + {"last", (getter)takewhile_last_get, (setter)NULL}, + {NULL} +}; + + static PyMethodDef takewhile_reduce_methods[] = { {"__reduce__", (PyCFunction)takewhile_reduce, METH_NOARGS, reduce_doc}, @@ -1361,7 +1388,7 @@ (iternextfunc)takewhile_next, /* tp_iternext */ takewhile_reduce_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + takewhile_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */