diff options
author | Guido van Rossum <guido@python.org> | 2001-04-23 14:08:49 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-04-23 14:08:49 (GMT) |
commit | 213c7a6aa5889f42495352199715a1c1a0833a00 (patch) | |
tree | 7559cd072f732c861cb28adb7192561a877fd6fb /Include | |
parent | 8b3d6ca3df1097752a1091b2c8f6d7de1b36a81d (diff) | |
download | cpython-213c7a6aa5889f42495352199715a1c1a0833a00.zip cpython-213c7a6aa5889f42495352199715a1c1a0833a00.tar.gz cpython-213c7a6aa5889f42495352199715a1c1a0833a00.tar.bz2 |
Mondo changes to the iterator stuff, without changing how Python code
sees it (test_iter.py is unchanged).
- Added a tp_iternext slot, which calls the iterator's next() method;
this is much faster for built-in iterators over built-in types
such as lists and dicts, speeding up pybench's ForLoop with about
25% compared to Python 2.1. (Now there's a good argument for
iterators. ;-)
- Renamed the built-in sequence iterator SeqIter, affecting the C API
functions for it. (This frees up the PyIter prefix for generic
iterator operations.)
- Added PyIter_Check(obj), which checks that obj's type has a
tp_iternext slot and that the proper feature flag is set.
- Added PyIter_Next(obj) which calls the tp_iternext slot. It has a
somewhat complex return condition due to the need for speed: when it
returns NULL, it may not have set an exception condition, meaning
the iterator is exhausted; when the exception StopIteration is set
(or a derived exception class), it means the same thing; any other
exception means some other error occurred.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/abstract.h | 13 | ||||
-rw-r--r-- | Include/iterobject.h | 6 | ||||
-rw-r--r-- | Include/object.h | 2 |
3 files changed, 18 insertions, 3 deletions
diff --git a/Include/abstract.h b/Include/abstract.h index c56c887..1dae5f1 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -470,11 +470,24 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ */ +/* Iterators */ + DL_IMPORT(PyObject *) PyObject_GetIter(PyObject *); /* Takes an object and returns an iterator for it. This is typically a new iterator but if the argument is an iterator, this returns itself. */ +#define PyIter_Check(obj) \ + (PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_ITER) && \ + (obj)->ob_type->tp_iternext != NULL) + + DL_IMPORT(PyObject *) PyIter_Next(PyObject *); + /* Takes an iterator object and calls its tp_iternext slot, + returning the next value. If the iterator is exhausted, + this can return NULL without setting an exception, *or* + NULL with a StopIteration exception. + NULL with any other exception means an error occurred. */ + /* Number Protocol:*/ DL_IMPORT(int) PyNumber_Check(PyObject *o); diff --git a/Include/iterobject.h b/Include/iterobject.h index 38454a4..bc18991 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -1,10 +1,10 @@ /* Iterators (the basic kind, over a sequence) */ -extern DL_IMPORT(PyTypeObject) PyIter_Type; +extern DL_IMPORT(PyTypeObject) PySeqIter_Type; -#define PyIter_Check(op) ((op)->ob_type == &PyIter_Type) +#define PySeqIter_Check(op) ((op)->ob_type == &PySeqIter_Type) -extern DL_IMPORT(PyObject *) PyIter_New(PyObject *); +extern DL_IMPORT(PyObject *) PySeqIter_New(PyObject *); extern DL_IMPORT(PyTypeObject) PyCallIter_Type; diff --git a/Include/object.h b/Include/object.h index 4a53835..0765748 100644 --- a/Include/object.h +++ b/Include/object.h @@ -201,6 +201,7 @@ typedef PyObject *(*reprfunc)(PyObject *); typedef long (*hashfunc)(PyObject *); typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); typedef struct _typeobject { PyObject_VAR_HEAD @@ -252,6 +253,7 @@ typedef struct _typeobject { /* Iterators */ getiterfunc tp_iter; + iternextfunc tp_iternext; #ifdef COUNT_ALLOCS /* these must be last and never explicitly initialized */ |