[Python-checkins] CVS: python/dist/src/Objects abstract.c,2.58,2.59 classobject.c,2.125,2.126 dictobject.c,2.78,2.79 stringobject.c,2.102,2.103
Guido van Rossum
gvanrossum@users.sourceforge.net
Fri, 20 Apr 2001 12:13:04 -0700
- Previous message: [Python-checkins] CVS: python/dist/src/Lib dis.py,1.33,1.34
- Next message: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.197,2.198 ceval.c,2.238,2.239 compile.c,2.196,2.197 exceptions.c,1.23,1.24 import.c,2.175,2.176
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv31661/Objects
Modified Files:
abstract.c classobject.c dictobject.c stringobject.c
Log Message:
Iterators phase 1. This comprises:
new slot tp_iter in type object, plus new flag Py_TPFLAGS_HAVE_ITER
new C API PyObject_GetIter(), calls tp_iter
new builtin iter(), with two forms: iter(obj), and iter(function, sentinel)
new internal object types iterobject and calliterobject
new exception StopIteration
new opcodes for "for" loops, GET_ITER and FOR_ITER (also supported by dis.py)
new magic number for .pyc files
new special method for instances: __iter__() returns an iterator
iteration over dictionaries: "for x in dict" iterates over the keys
iteration over files: "for x in file" iterates over lines
TODO:
documentation
test suite
decide whether to use a different way to spell iter(function, sentinal)
decide whether "for key in dict" is a good idea
use iterators in map/filter/reduce, min/max, and elsewhere (in/not in?)
speed tuning (make next() a slot tp_next???)
Index: abstract.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v
retrieving revision 2.58
retrieving revision 2.59
diff -C2 -r2.58 -r2.59
*** abstract.c 2001/03/21 18:40:58 2.58
--- abstract.c 2001/04/20 19:13:02 2.59
***************
*** 1739,1740 ****
--- 1739,1757 ----
return retval;
}
+
+ PyObject *
+ PyObject_GetIter(PyObject *o)
+ {
+ PyTypeObject *t = o->ob_type;
+ getiterfunc f = NULL;
+ if (PyType_HasFeature(t, Py_TPFLAGS_HAVE_ITER))
+ f = t->tp_iter;
+ if (f == NULL) {
+ if (PySequence_Check(o))
+ return PyIter_New(o);
+ PyErr_SetString(PyExc_TypeError, "iter() of non-sequence");
+ return NULL;
+ }
+ else
+ return (*f)(o);
+ }
Index: classobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v
retrieving revision 2.125
retrieving revision 2.126
diff -C2 -r2.125 -r2.126
*** classobject.c 2001/03/23 04:19:27 2.125
--- classobject.c 2001/04/20 19:13:02 2.126
***************
*** 849,853 ****
}
! static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr;
static int
--- 849,853 ----
}
! static PyObject *getitemstr, *setitemstr, *delitemstr, *lenstr, *iterstr;
static int
***************
*** 1713,1716 ****
--- 1713,1742 ----
+ /* Get the iterator */
+ static PyObject *
+ instance_getiter(PyInstanceObject *self)
+ {
+ PyObject *func;
+
+ if (iterstr == NULL)
+ iterstr = PyString_InternFromString("__iter__");
+ if (getitemstr == NULL)
+ getitemstr = PyString_InternFromString("__getitem__");
+
+ if ((func = instance_getattr(self, iterstr)) != NULL) {
+ PyObject *res = PyEval_CallObject(func, (PyObject *)NULL);
+ Py_DECREF(func);
+ return res;
+ }
+ PyErr_Clear();
+ if ((func = instance_getattr(self, getitemstr)) == NULL) {
+ PyErr_SetString(PyExc_TypeError, "iter() of non-sequence");
+ return NULL;
+ }
+ Py_DECREF(func);
+ return PyIter_New((PyObject *)self);
+ }
+
+
static PyNumberMethods instance_as_number = {
(binaryfunc)instance_add, /* nb_add */
***************
*** 1776,1780 ****
0, /* tp_clear */
instance_richcompare, /* tp_richcompare */
! offsetof(PyInstanceObject, in_weakreflist) /* tp_weaklistoffset */
};
--- 1802,1807 ----
0, /* tp_clear */
instance_richcompare, /* tp_richcompare */
! offsetof(PyInstanceObject, in_weakreflist), /* tp_weaklistoffset */
! (getiterfunc)instance_getiter, /* tp_iter */
};
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.78
retrieving revision 2.79
diff -C2 -r2.78 -r2.79
*** dictobject.c 2001/04/20 16:52:06 2.78
--- dictobject.c 2001/04/20 19:13:02 2.79
***************
*** 1325,1328 ****
--- 1325,1330 ----
};
+ staticforward PyObject *dictiter_new(dictobject *);
+
PyTypeObject PyDict_Type = {
PyObject_HEAD_INIT(&PyType_Type)
***************
*** 1351,1354 ****
--- 1353,1358 ----
(inquiry)dict_tp_clear, /* tp_clear */
0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictiter_new, /* tp_iter */
};
***************
*** 1393,1394 ****
--- 1397,1497 ----
return err;
}
+
+ /* Dictionary iterator type */
+
+ extern PyTypeObject PyDictIter_Type; /* Forward */
+
+ typedef struct {
+ PyObject_HEAD
+ dictobject *di_dict;
+ int di_size;
+ int di_pos;
+ } dictiterobject;
+
+ static PyObject *
+ dictiter_new(dictobject *dict)
+ {
+ dictiterobject *di;
+ di = PyObject_NEW(dictiterobject, &PyDictIter_Type);
+ if (di == NULL)
+ return NULL;
+ Py_INCREF(dict);
+ di->di_dict = dict;
+ di->di_size = dict->ma_size;
+ di->di_pos = 0;
+ return (PyObject *)di;
+ }
+
+ static void
+ dictiter_dealloc(dictiterobject *di)
+ {
+ Py_DECREF(di->di_dict);
+ PyObject_DEL(di);
+ }
+
+ static PyObject *
+ dictiter_next(dictiterobject *di, PyObject *args)
+ {
+ PyObject *key;
+ if (di->di_size != di->di_dict->ma_size) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "dictionary changed size during iteration");
+ return NULL;
+ }
+ if (PyDict_Next((PyObject *)(di->di_dict), &di->di_pos, &key, NULL)) {
+ Py_INCREF(key);
+ return key;
+ }
+ PyErr_SetObject(PyExc_StopIteration, Py_None);
+ return NULL;
+ }
+
+ static PyObject *
+ dictiter_getiter(PyObject *it)
+ {
+ Py_INCREF(it);
+ return it;
+ }
+
+ 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_getattr(dictiterobject *it, char *name)
+ {
+ return Py_FindMethod(dictiter_methods, (PyObject *)it, name);
+ }
+
+ PyTypeObject PyDictIter_Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "dictionary-iterator", /* tp_name */
+ sizeof(dictiterobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)dictiter_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)dictiter_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictiter_getiter, /* tp_iter */
+ };
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.102
retrieving revision 2.103
diff -C2 -r2.102 -r2.103
*** stringobject.c 2001/04/12 18:38:48 2.102
--- stringobject.c 2001/04/20 19:13:02 2.103
***************
*** 3233,3236 ****
--- 3233,3238 ----
{
if (interned) {
+ fprintf(stderr, "releasing interned strings\n");
+ PyDict_Clear(interned);
Py_DECREF(interned);
interned = NULL;
- Previous message: [Python-checkins] CVS: python/dist/src/Lib dis.py,1.33,1.34
- Next message: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.197,2.198 ceval.c,2.238,2.239 compile.c,2.196,2.197 exceptions.c,1.23,1.24 import.c,2.175,2.176
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]