diff options
author | Guido van Rossum <guido@python.org> | 2002-07-16 20:07:32 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-07-16 20:07:32 (GMT) |
commit | 86103ae53161a136a53d031190c2d0579dba2abf (patch) | |
tree | ab25d196fdfec182a131b3472b6559053c16c4f6 /Objects/listobject.c | |
parent | 9534e14033f26b32ed75c02a6a51bfe47c7f16a9 (diff) | |
download | cpython-86103ae53161a136a53d031190c2d0579dba2abf.zip cpython-86103ae53161a136a53d031190c2d0579dba2abf.tar.gz cpython-86103ae53161a136a53d031190c2d0579dba2abf.tar.bz2 |
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).
Diffstat (limited to 'Objects/listobject.c')
-rw-r--r-- | Objects/listobject.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c index 12a9272..b80e395 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 */ }; - |