[Python-checkins] python/dist/src/Objects listobject.c,2.209,2.210

tim_one at users.sourceforge.net tim_one at users.sourceforge.net
Thu Jul 29 06:07:22 CEST 2004


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

Modified Files:
	listobject.c 
Log Message:
Fix obscure breakage (relative to 2.3) in listsort:  the test for list
mutation during list.sort() used to rely on that listobject.c always
NULL'ed ob_item when ob_size fell to 0.  That's no longer true, so the
test for list mutation during a sort is no longer reliable.  Changed the
test to rely instead on that listobject.c now never NULLs-out ob_item
after (if ever) ob_item gets a non-NULL value.  This new assumption is
also documented now, as a required invariant in listobject.h.

The new assumption allowed some real simplification to some of the
hairier code in listsort(), so is a Good Thing on that count.


Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.209
retrieving revision 2.210
diff -C2 -d -r2.209 -r2.210
*** listobject.c	29 Jul 2004 02:29:26 -0000	2.209
--- listobject.c	29 Jul 2004 04:07:15 -0000	2.210
***************
*** 1907,1911 ****
  	int saved_ob_size, saved_allocated;
  	PyObject **saved_ob_item;
- 	PyObject **empty_ob_item;
  	PyObject *compare = NULL;
  	PyObject *result = NULL;	/* guilty until proved innocent */
--- 1907,1910 ----
***************
*** 1942,1948 ****
  	saved_ob_item = self->ob_item;
  	saved_allocated = self->allocated;
! 	self->ob_size = 0;
! 	self->ob_item = empty_ob_item = PyMem_NEW(PyObject *, 0);
! 	self->allocated = 0;
  
  	if (keyfunc != NULL) {
--- 1941,1946 ----
  	saved_ob_item = self->ob_item;
  	saved_allocated = self->allocated;
! 	self->ob_size = self->allocated = 0;
! 	self->ob_item = NULL;
  
  	if (keyfunc != NULL) {
***************
*** 1958,1973 ****
  					Py_DECREF(kvpair);
  				}
- 				if (self->ob_item != empty_ob_item
- 				    || self->ob_size) {
- 					/* If the list changed *as well* we
- 					   have two errors.  We let the first
- 					   one "win", but we shouldn't let
- 					   what's in the list currently
- 					   leak. */
- 					(void)list_ass_slice(
- 						self, 0, self->ob_size,
- 						(PyObject *)NULL);
- 				}
- 
  				goto dsu_fail;
  			}
--- 1956,1959 ----
***************
*** 2045,2056 ****
  	}
  
! 	if (self->ob_item != empty_ob_item || self->ob_size) {
! 		/* The user mucked with the list during the sort. */
! 		(void)list_ass_slice(self, 0, self->ob_size, (PyObject *)NULL);
! 		if (result != NULL) {
! 			PyErr_SetString(PyExc_ValueError,
! 					"list modified during sort");
! 			result = NULL;
! 		}
  	}
  
--- 2031,2040 ----
  	}
  
! 	if (self->ob_item != NULL && result != NULL) {
! 		/* The user mucked with the list during the sort,
! 		 * and we don't already have another error to report.
! 		 */
! 		PyErr_SetString(PyExc_ValueError, "list modified during sort");
! 		result = NULL;
  	}
  
***************
*** 2061,2066 ****
  
  dsu_fail:
! 	if (self->ob_item == empty_ob_item)
! 		PyMem_FREE(empty_ob_item);
  	self->ob_size = saved_ob_size;
  	self->ob_item = saved_ob_item;
--- 2045,2052 ----
  
  dsu_fail:
! 	if (self->ob_item != NULL) {
! 		(void)list_ass_slice(self, 0, self->ob_size, (PyObject *)NULL);
! 		PyMem_FREE(self->ob_item);
! 	}
  	self->ob_size = saved_ob_size;
  	self->ob_item = saved_ob_item;



More information about the Python-checkins mailing list