[Zope-Checkins] CVS: Zope3/lib/python/Persistence/BTrees - BTreeItemsTemplate.c:1.9
Tim Peters
tim.one@comcast.net
Wed, 17 Jul 2002 16:40:07 -0400
Update of /cvs-repository/Zope3/lib/python/Persistence/BTrees
In directory cvs.zope.org:/tmp/cvs-serv29274
Modified Files:
BTreeItemsTemplate.c
Log Message:
Refinements due to clarification of the iteration protocol recently
hammered out on Python-Dev:
+ It's unnecessary and undesirable for an iterator to supply both
tp_iternext and an explicit next() method. Got rid of the latter
for BTreeItems iterators. Python supplies a next() method wrapper
automatically then.
+ Since the BTreeIter_next() function no longer has to serve for both
tp_iternext and explict next(), remove the coded for explicitly raising
StopIteration at termination. That's required of explicit next()
methods, but not necessary for tp_iternext slots (and is also undesirable
for them, because it costs extra cycles and the caller may not require
it).
+ As was recently done for dict iterators in the core, if the BTreeItems
iterator detects that mutation has occurred between calls to
BTreeIter_next, the error it raises is made sticky (i.e., call the
iterator again, and you're going to get the same complaint again). It's
quite unlikely that a BTreeItems iterator will detect mutation, though.
+ The BTreeItems iterator already made StopIteration a sink state, so
nothing new to do there.
=== Zope3/lib/python/Persistence/BTrees/BTreeItemsTemplate.c 1.8 => 1.9 ===
PyObject_Del(bi);
}
-/* The implementation of the iterator's .next() method. Returns "the next"
- * item; returns NULL if error; returns NULL and sets StopIteration if the
+/* The implementation of the iterator's tp_iternext slot. Returns "the next"
+ * item; returns NULL if error; returns NULL without setting an error if the
* iteration is exhausted (that's the way to terminate the iteration protocol).
*/
static PyObject *
@@ -617,18 +617,18 @@
int i = items->currentoffset;
Bucket *bucket = items->currentbucket;
- if (bucket == NULL) {
- PyErr_SetObject(PyExc_StopIteration, Py_None);
+ if (bucket == NULL) /* iteration termination is sticky */
return NULL;
- }
PER_USE_OR_RETURN(bucket, NULL);
if (i >= bucket->len) {
- /* We never leave this routine with i >= len: somebody else
- * mutated the current bucket.
+ /* We never leave this routine normally with i >= len: somebody
+ * else mutated the current bucket.
*/
PyErr_SetString(PyExc_RuntimeError,
"the bucket being iterated changed size");
+ /* Arrange for that this error is sticky too. */
+ items->currentoffset = INT_MAX;
goto Done;
}
@@ -664,12 +664,6 @@
return it;
}
-static PyMethodDef btreeiter_methods[] = {
- {"next", (PyCFunction)BTreeIter_next, METH_VARARGS,
- "it.next() -- get the next value, or raise StopIteration"},
- {NULL, NULL} /* sentinel */
-};
-
static PyTypeObject BTreeIter_Type = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -700,7 +694,7 @@
0, /* tp_weaklistoffset */
(getiterfunc)BTreeIter_getiter, /* tp_iter */
(iternextfunc)BTreeIter_next, /* tp_iternext */
- btreeiter_methods, /* tp_methods */
+ 0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */