[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.73,2.73.2.1
Guido van Rossum
gvanrossum@usw-pr-cvs1.sourceforge.net
Tue, 13 Mar 2001 08:32:05 -0800
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv15136
Modified Files:
Tag: iter-branch
dictobject.c
Log Message:
Another *EXPERIMENTAL* feature on the "iter-branch" branch: implement
"if key in dict" and "for key in dict".
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.73
retrieving revision 2.73.2.1
diff -C2 -r2.73 -r2.73.2.1
*** dictobject.c 2001/01/18 00:39:02 2.73
--- dictobject.c 2001/03/13 16:32:03 2.73.2.1
***************
*** 1219,1222 ****
--- 1219,1256 ----
}
+ static int
+ dict_contains(dictobject *mp, PyObject *key)
+ {
+ long hash;
+
+ #ifdef CACHE_HASH
+ if (!PyString_Check(key) ||
+ (hash = ((PyStringObject *) key)->ob_shash) == -1)
+ #endif
+ {
+ hash = PyObject_Hash(key);
+ if (hash == -1)
+ return -1;
+ }
+ return (mp->ma_size != 0
+ && (mp->ma_lookup)(mp, key, hash)->me_value != NULL);
+ }
+
+ staticforward PyObject *dictiter_new(dictobject *);
+
+ /* Hack to implement "key in dict" */
+ static PySequenceMethods dict_as_sequence = {
+ 0, /* sq_length */
+ 0, /* sq_concat */
+ 0, /* sq_repeat */
+ 0, /* sq_item */
+ 0, /* sq_slice */
+ 0, /* sq_ass_item */
+ 0, /* sq_ass_slice */
+ (objobjproc)dict_contains, /* sq_contains */
+ 0, /* sq_inplace_concat */
+ 0, /* sq_inplace_repeat */
+ };
+
PyTypeObject PyDict_Type = {
PyObject_HEAD_INIT(&PyType_Type)
***************
*** 1232,1236 ****
(reprfunc)dict_repr, /* tp_repr */
0, /* tp_as_number */
! 0, /* tp_as_sequence */
&dict_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
--- 1266,1270 ----
(reprfunc)dict_repr, /* tp_repr */
0, /* tp_as_number */
! &dict_as_sequence, /* tp_as_sequence */
&dict_as_mapping, /* tp_as_mapping */
0, /* tp_hash */
***************
*** 1245,1248 ****
--- 1279,1284 ----
(inquiry)dict_tp_clear, /* tp_clear */
0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)dictiter_new, /* tp_iter */
};
***************
*** 1287,1288 ****
--- 1323,1423 ----
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_IndexError, 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 IndexError"},
+ {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 */
+ };