[Python-checkins] python/dist/src/Modules collectionsmodule.c, 1.3, 1.4

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Fri Feb 6 21:45:24 EST 2004


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

Modified Files:
	collectionsmodule.c 
Log Message:
* Fix ref counting in extend() and extendleft().
* Let deques support reversed().



Index: collectionsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/collectionsmodule.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** collectionsmodule.c	6 Feb 2004 19:04:56 -0000	1.3
--- collectionsmodule.c	7 Feb 2004 02:45:22 -0000	1.4
***************
*** 189,194 ****
  		if (deque->rightindex == BLOCKLEN) {
  			block *b = newblock(deque->rightblock, NULL);
! 			if (b == NULL)
  				return NULL;
  			assert(deque->rightblock->rightlink == NULL);
  			deque->rightblock->rightlink = b;
--- 189,197 ----
  		if (deque->rightindex == BLOCKLEN) {
  			block *b = newblock(deque->rightblock, NULL);
! 			if (b == NULL) {
! 				Py_DECREF(item);
! 				Py_DECREF(it);
  				return NULL;
+ 			}
  			assert(deque->rightblock->rightlink == NULL);
  			deque->rightblock->rightlink = b;
***************
*** 196,200 ****
  			deque->rightindex = 0;
  		}
- 		Py_INCREF(item);
  		deque->rightblock->data[deque->rightindex] = item;
  	}
--- 199,202 ----
***************
*** 222,227 ****
  		if (deque->leftindex == -1) {
  			block *b = newblock(NULL, deque->leftblock);
! 			if (b == NULL)
  				return NULL;
  			assert(deque->leftblock->leftlink == NULL);
  			deque->leftblock->leftlink = b;
--- 224,232 ----
  		if (deque->leftindex == -1) {
  			block *b = newblock(NULL, deque->leftblock);
! 			if (b == NULL) {
! 				Py_DECREF(item);
! 				Py_DECREF(it);
  				return NULL;
+ 			}
  			assert(deque->leftblock->leftlink == NULL);
  			deque->leftblock->leftlink = b;
***************
*** 229,233 ****
  			deque->leftindex = BLOCKLEN - 1;
  		}
- 		Py_INCREF(item);
  		deque->leftblock->data[deque->leftindex] = item;
  	}
--- 234,237 ----
***************
*** 445,448 ****
--- 449,455 ----
  
  static PyObject *deque_iter(dequeobject *deque);
+ static PyObject *deque_reviter(dequeobject *deque);
+ PyDoc_STRVAR(reversed_doc, 
+ 	"D.__reversed__() -- return a reverse iterator over the deque");
  
  static PyMethodDef deque_methods[] = {
***************
*** 461,464 ****
--- 468,473 ----
  	{"__reduce__",	(PyCFunction)deque_reduce,	
  		METH_NOARGS,	 reduce_doc},
+ 	{"__reversed__",	(PyCFunction)deque_reviter,	
+ 		METH_NOARGS,	 reversed_doc},
  	{"extend",		(PyCFunction)deque_extend,	
  		METH_O,		 extend_doc},
***************
*** 609,612 ****
--- 618,698 ----
  };
  
+ /*********************** Deque Reverse Iterator **************************/
+ 
+ PyTypeObject dequereviter_type;
+ 
+ static PyObject *
+ deque_reviter(dequeobject *deque)
+ {
+ 	dequeiterobject *it;
+ 
+ 	it = PyObject_New(dequeiterobject, &dequereviter_type);
+ 	if (it == NULL)
+ 		return NULL;
+ 	it->b = deque->rightblock;
+ 	it->index = deque->rightindex;
+ 	Py_INCREF(deque);
+ 	it->deque = deque;
+ 	it->len = deque->len;
+ 	return (PyObject *)it;
+ }
+ 
+ static PyObject *
+ dequereviter_next(dequeiterobject *it)
+ {
+ 	PyObject *item;
+ 	if (it->b == it->deque->leftblock && it->index < it->deque->leftindex)
+ 		return NULL;
+ 
+ 	if (it->len != it->deque->len) {
+ 		it->len = -1; /* Make this state sticky */
+ 		PyErr_SetString(PyExc_RuntimeError,
+ 				"deque changed size during iteration");
+ 		return NULL;
+ 	}
+ 
+ 	item = it->b->data[it->index];
+ 	it->index--;
+ 	if (it->index == -1 && it->b->leftlink != NULL) {
+ 		it->b = it->b->leftlink;
+ 		it->index = BLOCKLEN - 1;
+ 	}
+ 	Py_INCREF(item);
+ 	return item;
+ }
+ 
+ PyTypeObject dequereviter_type = {
+ 	PyObject_HEAD_INIT(NULL)
+ 	0,					/* ob_size */
+ 	"deque_reverse_iterator",		/* tp_name */
+ 	sizeof(dequeiterobject),		/* tp_basicsize */
+ 	0,					/* tp_itemsize */
+ 	/* methods */
+ 	(destructor)dequeiter_dealloc,		/* tp_dealloc */
+ 	0,					/* tp_print */
+ 	0,					/* 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 */
+ 	PyObject_GenericGetAttr,		/* 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 */
+ 	PyObject_SelfIter,			/* tp_iter */
+ 	(iternextfunc)dequereviter_next,	/* tp_iternext */
+ 	0,
+ };
+ 
  /* module level code ********************************************************/
  
***************
*** 630,633 ****
--- 716,722 ----
  		return;	
  
+ 	if (PyType_Ready(&dequereviter_type) < 0)
+ 		return;
+ 
  	return;
  }




More information about the Python-checkins mailing list