From: Guido van Rossum Date: Tue, 16 Jul 2002 20:07:32 +0000 (+0000) Subject: Make StopIteration a sink state. This is done by clearing out the X-Git-Tag: v2.3c1~4991 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=86103ae53161a136a53d031190c2d0579dba2abf;p=python Make StopIteration a sink state. This is done by clearing out the it_seq field when the end of the list is reached. Also remove the next() method -- one is supplied automatically by PyType_Ready() because the tp_iternext slot is set. That's a good thing, because the implementation given here was buggy (it never raised StopIteration). --- diff --git a/Objects/listobject.c b/Objects/listobject.c index 12a92727ae..b80e395a11 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1,4 +1,3 @@ - /* List object implementation */ #include "Python.h" @@ -2016,7 +2015,7 @@ static PyTypeObject immutable_list_type = { typedef struct { PyObject_HEAD long it_index; - PyListObject *it_seq; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ } listiterobject; PyTypeObject PyListIter_Type; @@ -2044,13 +2043,15 @@ static void listiter_dealloc(listiterobject *it) { _PyObject_GC_UNTRACK(it); - Py_DECREF(it->it_seq); + Py_XDECREF(it->it_seq); PyObject_GC_Del(it); } static int listiter_traverse(listiterobject *it, visitproc visit, void *arg) { + if (it->it_seq == NULL) + return 0; return visit((PyObject *)it->it_seq, arg); } @@ -2070,6 +2071,8 @@ listiter_next(listiterobject *it) assert(it != NULL); seq = it->it_seq; + if (seq == NULL) + return NULL; assert(PyList_Check(seq)); if (it->it_index < PyList_GET_SIZE(seq)) { @@ -2078,15 +2081,12 @@ listiter_next(listiterobject *it) Py_INCREF(item); return item; } + + Py_DECREF(seq); + it->it_seq = NULL; return NULL; } -static PyMethodDef listiter_methods[] = { - {"next", (PyCFunction)listiter_next, METH_NOARGS, - "it.next() -- get the next value, or raise StopIteration"}, - {NULL, NULL} /* sentinel */ -}; - PyTypeObject PyListIter_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ @@ -2117,7 +2117,7 @@ PyTypeObject PyListIter_Type = { 0, /* tp_weaklistoffset */ (getiterfunc)listiter_getiter, /* tp_iter */ (iternextfunc)listiter_next, /* tp_iternext */ - listiter_methods, /* tp_methods */ + 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -2125,4 +2125,3 @@ PyTypeObject PyListIter_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ }; -