[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 */
+ };