[Python-checkins] python/dist/src/Modules collectionsmodule.c, 1.7, 1.8

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sat Feb 28 21:15:58 EST 2004


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24444/Modules

Modified Files:
	collectionsmodule.c 
Log Message:
Improvements to collections.deque():

* Add doctests for the examples in the library reference.
* Add two methods, left() and right(), modeled after deques in C++ STL.
* Apply the new method to asynchat.py.
* Add comparison operators to make deques more substitutable for lists.
* Replace the LookupErrors with IndexErrors to more closely match lists.



Index: collectionsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/collectionsmodule.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** collectionsmodule.c	28 Feb 2004 15:56:27 -0000	1.7
--- collectionsmodule.c	29 Feb 2004 02:15:56 -0000	1.8
***************
*** 35,38 ****
--- 35,40 ----
  } dequeobject;
  
+ PyTypeObject deque_type;
+ 
  static PyObject *
  deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
***************
*** 110,114 ****
  
  	if (deque->len == 0) {
! 		PyErr_SetString(PyExc_LookupError, "pop from an empty deque");
  		return NULL;
  	}
--- 112,116 ----
  
  	if (deque->len == 0) {
! 		PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
  		return NULL;
  	}
***************
*** 145,149 ****
  
  	if (deque->len == 0) {
! 		PyErr_SetString(PyExc_LookupError, "pop from an empty deque");
  		return NULL;
  	}
--- 147,151 ----
  
  	if (deque->len == 0) {
! 		PyErr_SetString(PyExc_IndexError, "pop from an empty deque");
  		return NULL;
  	}
***************
*** 176,179 ****
--- 178,213 ----
  
  static PyObject *
+ deque_right(dequeobject *deque, PyObject *unused)
+ {
+ 	PyObject *item;
+ 
+ 	if (deque->len == 0) {
+ 		PyErr_SetString(PyExc_IndexError, "deque is empty");
+ 		return NULL;
+ 	}
+ 	item = deque->rightblock->data[deque->rightindex];
+ 	Py_INCREF(item);
+ 	return item;
+ }
+ 
+ PyDoc_STRVAR(right_doc, "Return the rightmost element.");
+ 
+ static PyObject *
+ deque_left(dequeobject *deque, PyObject *unused)
+ {
+ 	PyObject *item;
+ 
+ 	if (deque->len == 0) {
+ 		PyErr_SetString(PyExc_IndexError, "deque is empty");
+ 		return NULL;
+ 	}
+ 	item = deque->leftblock->data[deque->leftindex];
+ 	Py_INCREF(item);
+ 	return item;
+ }
+ 
+ PyDoc_STRVAR(left_doc, "Return the leftmost element.");
+ 
+ static PyObject *
  deque_extend(dequeobject *deque, PyObject *iterable)
  {
***************
*** 468,471 ****
--- 502,581 ----
  }
  
+ static PyObject *
+ deque_richcompare(PyObject *v, PyObject *w, int op)
+ {
+ 	PyObject *it1=NULL, *it2=NULL, *x, *y;
+ 	int i, b, vs, ws, minlen, cmp=-1;
+ 
+ 	if (v->ob_type != &deque_type || w->ob_type != &deque_type) {
+ 		Py_INCREF(Py_NotImplemented);
+ 		return Py_NotImplemented;
+ 	}
+ 
+ 	/* Shortcuts */
+ 	vs = ((dequeobject *)v)->len;
+ 	ws = ((dequeobject *)w)->len;
+ 	if (op == Py_EQ) {
+ 		if (v == w)
+ 			Py_RETURN_TRUE;
+ 		if (vs != ws)
+ 			Py_RETURN_FALSE;
+ 	}
+ 	if (op == Py_NE) {
+ 		if (v == w)
+ 			Py_RETURN_FALSE;
+ 		if (vs != ws)
+ 			Py_RETURN_TRUE;
+ 	}
+ 
+ 	/* Search for the first index where items are different */
+ 	it1 = PyObject_GetIter(v);
+ 	if (it1 == NULL)
+ 		goto done;
+ 	it2 = PyObject_GetIter(w);
+ 	if (it2 == NULL)
+ 		goto done;
+ 	minlen = (vs < ws)  ?  vs  :  ws;
+ 	for (i=0 ; i < minlen ; i++) {
+ 		x = PyIter_Next(it1);
+ 		if (x == NULL)
+ 			goto done;
+ 		y = PyIter_Next(it2);
+ 		if (y == NULL) {
+ 			Py_DECREF(x);
+ 			goto done;
+ 		}
+ 		b = PyObject_RichCompareBool(x, y, Py_EQ);
+ 		if (b == 0) {
+ 			cmp = PyObject_RichCompareBool(x, y, op);
+ 			Py_DECREF(x);
+ 			Py_DECREF(y);
+ 			goto done;
+ 		}
+ 		Py_DECREF(x);
+ 		Py_DECREF(y);
+ 		if (b == -1)
+ 			goto done;
+ 	}
+ 	/* Elements are equal through minlen.  The longest input is the greatest */
+ 	switch (op) {
+ 	case Py_LT: cmp = vs <  ws; break;
+ 	case Py_LE: cmp = vs <= ws; break;
+ 	case Py_EQ: cmp = vs == ws; break;
+ 	case Py_NE: cmp = vs != ws; break;
+ 	case Py_GT: cmp = vs >  ws; break;
+ 	case Py_GE: cmp = vs >= ws; break;
+ 	}
+ 	
+ done:
+ 	Py_XDECREF(it1);
+ 	Py_XDECREF(it2);
+ 	if (cmp == 1)
+ 		Py_RETURN_TRUE;
+ 	if (cmp == 0)
+ 		Py_RETURN_FALSE;
+ 	return NULL;
+ }
+ 
  static int
  deque_init(dequeobject *deque, PyObject *args, PyObject *kwds)
***************
*** 510,513 ****
--- 620,625 ----
  	{"extendleft",	(PyCFunction)deque_extendleft,	
  		METH_O,		 extendleft_doc},
+ 	{"left",		(PyCFunction)deque_left,	
+ 		METH_NOARGS,	 left_doc},
  	{"pop",			(PyCFunction)deque_pop,	
  		METH_NOARGS,	 pop_doc},
***************
*** 518,521 ****
--- 630,635 ----
  	{"__reversed__",	(PyCFunction)deque_reviter,	
  		METH_NOARGS,	 reversed_doc},
+ 	{"right",		(PyCFunction)deque_right,	
+ 		METH_NOARGS,	 right_doc},
  	{"rotate",		(PyCFunction)deque_rotate,	
  		METH_VARARGS,	rotate_doc},
***************
*** 554,558 ****
  	(traverseproc)set_traverse,	/* tp_traverse */
  	(inquiry)deque_clear,		/* tp_clear */
! 	0,				/* tp_richcompare */
  	0,				/* tp_weaklistoffset*/
  	(getiterfunc)deque_iter,	/* tp_iter */
--- 668,672 ----
  	(traverseproc)set_traverse,	/* tp_traverse */
  	(inquiry)deque_clear,		/* tp_clear */
! 	(richcmpfunc)deque_richcompare,	/* tp_richcompare */
  	0,				/* tp_weaklistoffset*/
  	(getiterfunc)deque_iter,	/* tp_iter */




More information about the Python-checkins mailing list