[Python-checkins] python/dist/src/Objects dictobject.c,2.126,2.127
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Tue, 16 Jul 2002 13:30:25 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv4011
Modified Files:
dictobject.c
Log Message:
Make StopIteration a sink state. This is done by clearing out the
di_dict field when the end of the list is reached. Also make the
error ("dictionary changed size during iteration") a sticky state.
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).
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.126
retrieving revision 2.127
diff -C2 -d -r2.126 -r2.127
*** dictobject.c 13 Jun 2002 20:32:57 -0000 2.126
--- dictobject.c 16 Jul 2002 20:30:22 -0000 2.127
***************
*** 1917,1921 ****
typedef struct {
PyObject_HEAD
! dictobject *di_dict;
int di_used;
int di_pos;
--- 1917,1921 ----
typedef struct {
PyObject_HEAD
! dictobject *di_dict; /* Set to NULL when iterator is exhausted */
int di_used;
int di_pos;
***************
*** 1941,1966 ****
dictiter_dealloc(dictiterobject *di)
{
! Py_DECREF(di->di_dict);
PyObject_Del(di);
}
static PyObject *
- dictiter_next(dictiterobject *di, PyObject *args)
- {
- PyObject *key, *value;
-
- if (di->di_used != di->di_dict->ma_used) {
- PyErr_SetString(PyExc_RuntimeError,
- "dictionary changed size during iteration");
- return NULL;
- }
- if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
- return (*di->di_select)(key, value);
- }
- PyErr_SetObject(PyExc_StopIteration, Py_None);
- return NULL;
- }
-
- static PyObject *
dictiter_getiter(PyObject *it)
{
--- 1941,1949 ----
dictiter_dealloc(dictiterobject *di)
{
! Py_XDECREF(di->di_dict);
PyObject_Del(di);
}
static PyObject *
dictiter_getiter(PyObject *it)
{
***************
*** 1969,1990 ****
}
- static PyMethodDef dictiter_methods[] = {
- {"next", (PyCFunction)dictiter_next, METH_VARARGS,
- "it.next() -- get the next value, or raise StopIteration"},
- {NULL, NULL} /* sentinel */
- };
-
static PyObject *dictiter_iternext(dictiterobject *di)
{
PyObject *key, *value;
if (di->di_used != di->di_dict->ma_used) {
PyErr_SetString(PyExc_RuntimeError,
"dictionary changed size during iteration");
return NULL;
}
! if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value)) {
return (*di->di_select)(key, value);
! }
return NULL;
}
--- 1952,1973 ----
}
static PyObject *dictiter_iternext(dictiterobject *di)
{
PyObject *key, *value;
+ if (di->di_dict == NULL)
+ return NULL;
+
if (di->di_used != di->di_dict->ma_used) {
PyErr_SetString(PyExc_RuntimeError,
"dictionary changed size during iteration");
+ di->di_used = -1; /* Make this state sticky */
return NULL;
}
! if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, &value))
return (*di->di_select)(key, value);
!
! Py_DECREF(di->di_dict);
! di->di_dict = NULL;
return NULL;
}
***************
*** 2020,2024 ****
(getiterfunc)dictiter_getiter, /* tp_iter */
(iternextfunc)dictiter_iternext, /* tp_iternext */
! dictiter_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
--- 2003,2007 ----
(getiterfunc)dictiter_getiter, /* tp_iter */
(iternextfunc)dictiter_iternext, /* tp_iternext */
! 0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */