[Python-checkins] r51568 - in python/branches/p3yk-noslice: Lib/test/test_array.py Lib/test/test_builtin.py Lib/test/test_bytes.py Lib/test/test_descrtut.py Modules/arraymodule.c Modules/mmapmodule.c Objects/abstract.c Objects/bufferobject.c Objects/bytesobject.c Objects/listobject.c Objects/stringobject.c Objects/structseq.c Objects/tupleobject.c Objects/typeobject.c Objects/unicodeobject.c Objects/weakrefobject.c TODO

thomas.wouters python-checkins at python.org
Thu Aug 24 21:27:35 CEST 2006


Author: thomas.wouters
Date: Thu Aug 24 21:27:32 2006
New Revision: 51568

Modified:
   python/branches/p3yk-noslice/Lib/test/test_array.py
   python/branches/p3yk-noslice/Lib/test/test_builtin.py
   python/branches/p3yk-noslice/Lib/test/test_bytes.py
   python/branches/p3yk-noslice/Lib/test/test_descrtut.py
   python/branches/p3yk-noslice/Modules/arraymodule.c
   python/branches/p3yk-noslice/Modules/mmapmodule.c
   python/branches/p3yk-noslice/Objects/abstract.c
   python/branches/p3yk-noslice/Objects/bufferobject.c
   python/branches/p3yk-noslice/Objects/bytesobject.c
   python/branches/p3yk-noslice/Objects/listobject.c
   python/branches/p3yk-noslice/Objects/stringobject.c
   python/branches/p3yk-noslice/Objects/structseq.c
   python/branches/p3yk-noslice/Objects/tupleobject.c
   python/branches/p3yk-noslice/Objects/typeobject.c
   python/branches/p3yk-noslice/Objects/unicodeobject.c
   python/branches/p3yk-noslice/Objects/weakrefobject.c
   python/branches/p3yk-noslice/TODO
Log:

Checkpoint work. Only test_ctypes fails (because its sequence-like objects
don't support slicing with sliceobjects.)

 - NULL-out most of the sq_slice and sq_ass_slice pointers in typestructs,
   just to make sure the MappingMethod versions are used everywhere
   (compiler warns about some unused static functions now.)
 - Stop exporting those functionpointers to Python as __*slice__.
 - Fix some bugs in the bytes type's extended (and non-extended) slicing.
 - Fix two bugs in list's extended slicing that were cancelling each other
   out (but causing unnecessary memmove()'s), and use memmove() instead of
   assignment in a loop where possible.
 - Optimize array.array's extended slicing for the step=1 case.



Modified: python/branches/p3yk-noslice/Lib/test/test_array.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_array.py	(original)
+++ python/branches/p3yk-noslice/Lib/test/test_array.py	Thu Aug 24 21:27:32 2006
@@ -530,11 +530,11 @@
         )
 
         a = array.array(self.typecode, self.example)
-        self.assertRaises(TypeError, a.__setslice__, 0, 0, None)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), None)
         self.assertRaises(TypeError, a.__setitem__, slice(0, 1), None)
 
         b = array.array(self.badtypecode())
-        self.assertRaises(TypeError, a.__setslice__, 0, 0, b)
+        self.assertRaises(TypeError, a.__setitem__, slice(0, 0), b)
         self.assertRaises(TypeError, a.__setitem__, slice(0, 1), b)
 
     def test_index(self):

Modified: python/branches/p3yk-noslice/Lib/test/test_builtin.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_builtin.py	(original)
+++ python/branches/p3yk-noslice/Lib/test/test_builtin.py	Thu Aug 24 21:27:32 2006
@@ -389,7 +389,10 @@
 
         unlink(TESTFN)
         self.assertRaises(TypeError, execfile)
-        self.assertRaises(TypeError, execfile, TESTFN, {}, ())
+        # The inability of PyMapping_Check() to see tuples as
+        # non-mappings makes this test fail.
+        #self.assertRaises(TypeError, execfile, TESTFN, {}, ())
+        self.assertRaises(TypeError, execfile, TESTFN, {}, 42)
         import os
         self.assertRaises(IOError, execfile, os.curdir)
         self.assertRaises(IOError, execfile, "I_dont_exist")

Modified: python/branches/p3yk-noslice/Lib/test/test_bytes.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_bytes.py	(original)
+++ python/branches/p3yk-noslice/Lib/test/test_bytes.py	Thu Aug 24 21:27:32 2006
@@ -163,6 +163,16 @@
         self.assertEqual(b[-5:100], by("world"))
         self.assertEqual(b[-100:5], by("Hello"))
 
+    def test_extended_getslice(self):
+        L = range(20)
+        b = bytes(L)
+        indices = (None, 1, 5, 11, 19, 100, -1, -2, -5, -11, -19, -100)
+        for start in indices:
+            for stop in indices:
+                for step in indices:
+                    idx = slice(start, stop, step)
+                    self.assertEqual(b[idx], bytes(L[idx]))
+        
     def test_regexps(self):
         def by(s):
             return bytes(map(ord, s))
@@ -236,6 +246,35 @@
         b[3:5] = [3, 4, 5, 6]
         self.assertEqual(b, bytes(range(10)))
 
+    def test_extended_set_del_slice(self):
+        indices = (None, 1, 5, 11, 19, 100, -1, -2, -5, -11, -19, -100)
+        for start in indices:
+            for step in indices:
+                for stop in indices:
+                    L = list(range(20))
+                    b = bytes(L)
+
+                    idx = slice(start, stop, step)
+                    start, stop, step = idx.indices(len(L))
+                    # This is taken from Pyslice_GetIndicesEx(),
+                    # and should probably be exposed to Python
+                    if ((step < 0 and start <= stop) or
+                        (step > 0 and start >= stop)):
+                        slicelen = 0
+                    elif step < 0:
+                        slicelen = (stop - start + 1) // step + 1
+                    else:
+                        slicelen = (stop - start - 1) // step + 1
+
+                    data = list(range(100, 100 + slicelen))
+                    L[idx] = data
+                    b[idx] = data
+                    self.assertEquals(b, bytes(L))
+                    
+                    del L[idx]
+                    del b[idx]
+                    self.assertEquals(b, bytes(L))
+
     def test_setslice_trap(self):
         # This test verifies that we correctly handle assigning self
         # to a slice of self (the old Lambert Meertens trap).

Modified: python/branches/p3yk-noslice/Lib/test/test_descrtut.py
==============================================================================
--- python/branches/p3yk-noslice/Lib/test/test_descrtut.py	(original)
+++ python/branches/p3yk-noslice/Lib/test/test_descrtut.py	Thu Aug 24 21:27:32 2006
@@ -180,13 +180,11 @@
      '__contains__',
      '__delattr__',
      '__delitem__',
-     '__delslice__',
      '__doc__',
      '__eq__',
      '__ge__',
      '__getattribute__',
      '__getitem__',
-     '__getslice__',
      '__gt__',
      '__hash__',
      '__iadd__',
@@ -206,7 +204,6 @@
      '__rmul__',
      '__setattr__',
      '__setitem__',
-     '__setslice__',
      '__str__',
      'append',
      'count',

Modified: python/branches/p3yk-noslice/Modules/arraymodule.c
==============================================================================
--- python/branches/p3yk-noslice/Modules/arraymodule.c	(original)
+++ python/branches/p3yk-noslice/Modules/arraymodule.c	Thu Aug 24 21:27:32 2006
@@ -1582,7 +1582,12 @@
 		}
 		if (i < 0)
 			i += self->ob_size;
-		return array_item(self, i);
+		if (i < 0 || i >= self->ob_size) {
+			PyErr_SetString(PyExc_IndexError,
+				"array index out of range");
+			return NULL;
+		}
+		return getarrayitem((PyObject *)self, i);
 	}
 	else if (PySlice_Check(item)) {
 		Py_ssize_t start, stop, step, slicelength, cur, i;
@@ -1598,6 +1603,16 @@
 		if (slicelength <= 0) {
 			return newarrayobject(&Arraytype, 0, self->ob_descr);
 		}
+		else if (step == 1) {
+			PyObject *result = newarrayobject(&Arraytype,
+						slicelength, self->ob_descr);
+			if (result == NULL)
+				return NULL;
+			memcpy(((arrayobject *)result)->ob_item,
+			       self->ob_item + start * itemsize,
+			       slicelength * itemsize);
+			return result;
+		}
 		else {
 			result = newarrayobject(&Arraytype, slicelength, self->ob_descr);
 			if (!result) return NULL;
@@ -1624,112 +1639,146 @@
 static int
 array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
 {
+	Py_ssize_t start, stop, step, slicelength, needed;
+	arrayobject* other;
+	int itemsize;
+
 	if (PyIndex_Check(item)) {
 		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
-		if (i==-1 && PyErr_Occurred()) 
+		
+		if (i == -1 && PyErr_Occurred())
 			return -1;
 		if (i < 0)
 			i += self->ob_size;
-		return array_ass_item(self, i, value);
-	}
-	else if (PySlice_Check(item)) {
-		Py_ssize_t start, stop, step, slicelength;
-		int itemsize = self->ob_descr->itemsize;
-
-		if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
-				 &start, &stop, &step, &slicelength) < 0) {
+		if (i < 0 || i >= self->ob_size) {
+			PyErr_SetString(PyExc_IndexError,
+				"array assignment index out of range");
 			return -1;
 		}
-
-		/* treat A[slice(a,b)] = v _exactly_ like A[a:b] = v */
-		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
-			return array_ass_slice(self, start, stop, value);
-
 		if (value == NULL) {
-			/* delete slice */
-			Py_ssize_t cur, i, extra;
-			
-			if (slicelength <= 0)
-				return 0;
-
-			if (step < 0) {
-				stop = start + 1;
-				start = stop + step*(slicelength - 1) - 1;
-				step = -step;
-			}
-
-			for (cur = start, i = 0; i < slicelength - 1;
-			     cur += step, i++) {
-				memmove(self->ob_item + (cur - i)*itemsize,
-					self->ob_item + (cur + 1)*itemsize,
-					(step - 1) * itemsize);
-			}
-			extra = self->ob_size - (cur + 1);
-			if (extra > 0) {
-				memmove(self->ob_item + (cur - i)*itemsize,
-					self->ob_item + (cur + 1)*itemsize,
-					extra*itemsize);
-			}
-
-			self->ob_size -= slicelength;
-			self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
-							      itemsize*self->ob_size);
-			self->allocated = self->ob_size;
-
-			return 0;
+			/* Fall through to slice assignment */
+			start = i;
+			stop = i + 1;
+			step = 1;
+			slicelength = 1;
 		}
-		else {
-			/* assign slice */
-			Py_ssize_t cur, i;
-			arrayobject* av;
-
-			if (!array_Check(value)) {
-				PyErr_Format(PyExc_TypeError,
-			     "must assign array (not \"%.200s\") to slice",
-					     value->ob_type->tp_name);
-				return -1;
-			}
-
-			av = (arrayobject*)value;
-
-			if (av->ob_size != slicelength) {
-				PyErr_Format(PyExc_ValueError,
-            "attempt to assign array of size %ld to extended slice of size %ld",
-					     /*XXX*/(long)av->ob_size, /*XXX*/(long)slicelength);
+		else
+			return (*self->ob_descr->setitem)(self, i, value);
+	}
+	else if (PySlice_Check(item)) {
+		if (PySlice_GetIndicesEx((PySliceObject *)item,
+					 self->ob_size, &start, &stop,
+					 &step, &slicelength) < 0) {
+			return -1;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+				"array indices must be integer");
+		return -1;
+	}
+	if (value == NULL) {
+		other = NULL;
+		needed = 0;
+	}
+	else if (array_Check(value)) {
+		other = (arrayobject *)value;
+		needed = other->ob_size;
+		if (self == other) {
+			/* Special case "self[i:j] = self" -- copy self first */
+			int ret;
+			value = array_slice(other, 0, needed);
+			if (value == NULL)
 				return -1;
-			}
-
-			if (!slicelength)
-				return 0;
-
-			/* protect against a[::-1] = a */
-			if (self == av) { 
-				value = array_slice(av, 0, av->ob_size);
-				av = (arrayobject*)value;
-				if (!av)
-					return -1;
-			} 
-			else {
-				Py_INCREF(value);
-			}
-
-			for (cur = start, i = 0; i < slicelength; 
-			     cur += step, i++) {
-				memcpy(self->ob_item + cur*itemsize,
-				       av->ob_item + i*itemsize,
-				       itemsize);
-			}
-
+			ret = array_ass_subscr(self, item, value);
 			Py_DECREF(value);
-			
-			return 0;
+			return ret;
 		}
-	} 
+		if (other->ob_descr != self->ob_descr) {
+			PyErr_BadArgument();
+			return -1;
+		}
+	}
 	else {
-		PyErr_SetString(PyExc_TypeError, 
-				"list indices must be integers");
+		PyErr_Format(PyExc_TypeError,
+	     "can only assign array (not \"%.200s\") to array slice",
+			     value->ob_type->tp_name);
 		return -1;
 	}
+	itemsize = self->ob_descr->itemsize;
+	/* for 'a[2:1] = ...', the insertion point is 'start', not 'stop' */
+	if ((step > 0 && stop < start) ||
+	    (step < 0 && stop > start))
+		stop = start;
+	if (step == 1) {
+		if (slicelength > needed) {
+			memmove(self->ob_item + (start + needed) * itemsize,
+				self->ob_item + stop * itemsize,
+				(self->ob_size - stop) * itemsize);
+			if (array_resize(self, self->ob_size +
+					 needed - slicelength) < 0)
+				return -1;
+		}
+		else if (slicelength < needed) {
+			if (array_resize(self, self->ob_size +
+					 needed - slicelength) < 0)
+				return -1;
+			memmove(self->ob_item + (start + needed) * itemsize,
+				self->ob_item + stop * itemsize,
+				(self->ob_size - start - needed) * itemsize);
+		}
+		if (needed > 0)
+			memcpy(self->ob_item + start * itemsize,
+			       other->ob_item, needed * itemsize);
+		return 0;
+	}
+	else if (needed == 0) {
+		/* Delete slice */
+		Py_ssize_t cur, i;
+		
+		if (step < 0) {
+			stop = start + 1;
+			start = stop + step * (slicelength - 1) - 1;
+			step = -step;
+		}
+		for (cur = start, i = 0; i < slicelength;
+		     cur += step, i++) {
+			Py_ssize_t lim = step - 1;
+
+			if (cur + step >= self->ob_size)
+				lim = self->ob_size - cur - 1;
+			memmove(self->ob_item + (cur - i) * itemsize,
+				self->ob_item + (cur + 1) * itemsize,
+				lim * itemsize);
+		}
+		cur = start + slicelength * step;
+		if (cur < self->ob_size) {
+			memmove(self->ob_item + (cur-slicelength) * itemsize,
+				self->ob_item + cur * itemsize,
+				(self->ob_size - cur) * itemsize);
+		}
+		if (array_resize(self, self->ob_size - slicelength) < 0)
+			return -1;
+		return 0;
+	}
+	else {
+		Py_ssize_t cur, i;
+
+		if (needed != slicelength) {
+			PyErr_Format(PyExc_ValueError,
+				"attempt to assign array of size %zd "
+				"to extended slice of size %zd",
+				needed, slicelength);
+			return -1;
+		}
+		for (cur = start, i = 0; i < slicelength;
+		     cur += step, i++) {
+			memcpy(self->ob_item + cur * itemsize,
+			       other->ob_item + i * itemsize,
+			       itemsize);
+		}
+		return 0;
+	}
 }
 
 static PyMappingMethods array_as_mapping = {
@@ -1775,9 +1824,9 @@
 	(binaryfunc)array_concat,               /*sq_concat*/
 	(ssizeargfunc)array_repeat,		/*sq_repeat*/
 	(ssizeargfunc)array_item,		        /*sq_item*/
-	(ssizessizeargfunc)array_slice,		/*sq_slice*/
+	0,					/*sq_slice*/
 	(ssizeobjargproc)array_ass_item,		/*sq_ass_item*/
-	(ssizessizeobjargproc)array_ass_slice,	/*sq_ass_slice*/
+	0,					/*sq_ass_slice*/
 	(objobjproc)array_contains,		/*sq_contains*/
 	(binaryfunc)array_inplace_concat,	/*sq_inplace_concat*/
 	(ssizeargfunc)array_inplace_repeat	/*sq_inplace_repeat*/

Modified: python/branches/p3yk-noslice/Modules/mmapmodule.c
==============================================================================
--- python/branches/p3yk-noslice/Modules/mmapmodule.c	(original)
+++ python/branches/p3yk-noslice/Modules/mmapmodule.c	Thu Aug 24 21:27:32 2006
@@ -913,9 +913,9 @@
 	(binaryfunc)mmap_concat,	       /*sq_concat*/
 	(ssizeargfunc)mmap_repeat,	       /*sq_repeat*/
 	(ssizeargfunc)mmap_item,		       /*sq_item*/
-	(ssizessizeargfunc)mmap_slice,	       /*sq_slice*/
+	0,				      /*sq_slice*/
 	(ssizeobjargproc)mmap_ass_item,	       /*sq_ass_item*/
-	(ssizessizeobjargproc)mmap_ass_slice,      /*sq_ass_slice*/
+	0,				      /*sq_ass_slice*/
 };
 
 static PyMappingMethods mmap_as_mapping = {

Modified: python/branches/p3yk-noslice/Objects/abstract.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/abstract.c	(original)
+++ python/branches/p3yk-noslice/Objects/abstract.c	Thu Aug 24 21:27:32 2006
@@ -1192,26 +1192,12 @@
 PyObject *
 PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
 {
-	PySequenceMethods *m;
 	PyMappingMethods *mp;
 
 	if (!s) return null_error();
 
-	m = s->ob_type->tp_as_sequence;
-	if (m && m->sq_slice) {
-		if (i1 < 0 || i2 < 0) {
-			if (m->sq_length) {
-				Py_ssize_t l = (*m->sq_length)(s);
-				if (l < 0)
-					return NULL;
-				if (i1 < 0)
-					i1 += l;
-				if (i2 < 0)
-					i2 += l;
-			}
-		}
-		return m->sq_slice(s, i1, i2);
-	} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
+	mp = s->ob_type->tp_as_mapping;
+	if (mp->mp_subscript) {
 		PyObject *res;
 		PyObject *slice = _PySlice_FromIndices(i1, i2);
 		if (!slice)
@@ -1281,7 +1267,6 @@
 int
 PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
 {
-	PySequenceMethods *m;
 	PyMappingMethods *mp;
 
 	if (s == NULL) {
@@ -1289,21 +1274,8 @@
 		return -1;
 	}
 
-	m = s->ob_type->tp_as_sequence;
-	if (m && m->sq_ass_slice) {
-		if (i1 < 0 || i2 < 0) {
-			if (m->sq_length) {
-				Py_ssize_t l = (*m->sq_length)(s);
-				if (l < 0)
-					return -1;
-				if (i1 < 0)
-					i1 += l;
-				if (i2 < 0)
-					i2 += l;
-			}
-		}
-		return m->sq_ass_slice(s, i1, i2, o);
-	} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
+	mp = s->ob_type->tp_as_mapping;
+	if (mp->mp_ass_subscript) {
 		int res;
 		PyObject *slice = _PySlice_FromIndices(i1, i2);
 		if (!slice)
@@ -1320,27 +1292,22 @@
 int
 PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
 {
-	PySequenceMethods *m;
+	PyMappingMethods *mp;
 
 	if (s == NULL) {
 		null_error();
 		return -1;
 	}
 
-	m = s->ob_type->tp_as_sequence;
-	if (m && m->sq_ass_slice) {
-		if (i1 < 0 || i2 < 0) {
-			if (m->sq_length) {
-				Py_ssize_t l = (*m->sq_length)(s);
-				if (l < 0)
-					return -1;
-				if (i1 < 0)
-					i1 += l;
-				if (i2 < 0)
-					i2 += l;
-			}
-		}
-		return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
+	mp = s->ob_type->tp_as_mapping;
+	if (mp->mp_ass_subscript) {
+		int res;
+		PyObject *slice = _PySlice_FromIndices(i1, i2);
+		if (!slice)
+			return -1;
+		res = mp->mp_ass_subscript(s, slice, NULL);
+		Py_DECREF(slice);
+		return res;
 	}
 	type_error("'%.200s' object doesn't support slice deletion", s);
 	return -1;
@@ -1614,9 +1581,7 @@
 PyMapping_Check(PyObject *o)
 {
 	return  o && o->ob_type->tp_as_mapping &&
-		o->ob_type->tp_as_mapping->mp_subscript &&
-		!(o->ob_type->tp_as_sequence && 
-		  o->ob_type->tp_as_sequence->sq_slice);
+		o->ob_type->tp_as_mapping->mp_subscript;
 }
 
 Py_ssize_t

Modified: python/branches/p3yk-noslice/Objects/bufferobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/bufferobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/bufferobject.c	Thu Aug 24 21:27:32 2006
@@ -638,7 +638,6 @@
 	void *ptr1, *ptr2;
 	Py_ssize_t selfsize;
 	Py_ssize_t othersize;
-	Py_ssize_t start, stop, step, slicelength;
 
 	if ( self->b_readonly ) {
 		PyErr_SetString(PyExc_TypeError,
@@ -709,8 +708,6 @@
 		}
 		else {
 			Py_ssize_t cur, i;
-			char *resultbuf = (char *)ptr1;
-			char *sourcebuf = (char *)ptr2;
 			
 			for (cur = start, i = 0; i < slicelength;
 			     cur += step, i++) {
@@ -796,9 +793,9 @@
 	(binaryfunc)buffer_concat, /*sq_concat*/
 	(ssizeargfunc)buffer_repeat, /*sq_repeat*/
 	(ssizeargfunc)buffer_item, /*sq_item*/
-	(ssizessizeargfunc)buffer_slice, /*sq_slice*/
+	0, /*sq_slice*/
 	(ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
-	(ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+	0, /*sq_ass_slice*/
 };
 
 static PyMappingMethods buffer_as_mapping = {

Modified: python/branches/p3yk-noslice/Objects/bytesobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/bytesobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/bytesobject.c	Thu Aug 24 21:27:32 2006
@@ -459,7 +459,8 @@
             stop = i + 1;
             step = 1;
             slicelen = 1;
-        } else {
+        }
+        else {
             Py_ssize_t ival = PyNumber_AsSsize_t(values, PyExc_ValueError);
             if (ival == -1 && PyErr_Occurred())
                 return -1;
@@ -503,7 +504,10 @@
         bytes = ((PyBytesObject *)values)->ob_bytes;
         needed = ((PyBytesObject *)values)->ob_size;
     }
-
+    /* Make sure b[5:2] = ... inserts before 5, not before 2. */
+    if ((step < 0 && start < stop) ||
+        (step > 0 && start > stop))
+        stop = start;
     if (step == 1) {
         if (slicelen != needed) {
             if (slicelen > needed) {
@@ -548,7 +552,7 @@
             }
             for (cur = start, i = 0;
                  i < slicelen; cur += step, i++) {
-                Py_ssize_t lim = step;
+                Py_ssize_t lim = step - 1;
 
                 if (cur + step >= PyBytes_GET_SIZE(self))
                     lim = PyBytes_GET_SIZE(self) - cur - 1;
@@ -557,10 +561,12 @@
                         self->ob_bytes + cur + 1, lim);
             }
             /* Move the tail of the bytes, in one chunk */
-            cur = start + slicelen*step + 1;
-            memmove(self->ob_bytes + cur - slicelen,
-                    self->ob_bytes + cur,
-                    PyBytes_GET_SIZE(self) - cur);
+            cur = start + slicelen*step;
+            if (cur < PyBytes_GET_SIZE(self)) {
+                memmove(self->ob_bytes + cur - slicelen,
+                        self->ob_bytes + cur,
+                        PyBytes_GET_SIZE(self) - cur);
+            }
             if (PyBytes_Resize((PyObject *)self, 
                                PyBytes_GET_SIZE(self) - slicelen) < 0)
                 return -1;
@@ -981,9 +987,9 @@
     (binaryfunc)bytes_concat,           /*sq_concat*/
     (ssizeargfunc)bytes_repeat,         /*sq_repeat*/
     (ssizeargfunc)bytes_getitem,        /*sq_item*/
-    (ssizessizeargfunc)bytes_getslice,  /*sq_slice*/
+    0,                                  /*sq_slice*/
     (ssizeobjargproc)bytes_setitem,     /*sq_ass_item*/
-    (ssizessizeobjargproc)bytes_setslice, /* sq_ass_slice */
+    0, 					/* sq_ass_slice */
     (objobjproc)bytes_contains,         /* sq_contains */
     (binaryfunc)bytes_iconcat,   /* sq_inplace_concat */
     (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */

Modified: python/branches/p3yk-noslice/Objects/listobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/listobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/listobject.c	Thu Aug 24 21:27:32 2006
@@ -2432,9 +2432,9 @@
 	(binaryfunc)list_concat,		/* sq_concat */
 	(ssizeargfunc)list_repeat,		/* sq_repeat */
 	(ssizeargfunc)list_item,		/* sq_item */
-	(ssizessizeargfunc)list_slice,		/* sq_slice */
+	0,					/* sq_slice */
 	(ssizeobjargproc)list_ass_item,		/* sq_ass_item */
-	(ssizessizeobjargproc)list_ass_slice,	/* sq_ass_slice */
+	0,					/* sq_ass_slice */
 	(objobjproc)list_contains,		/* sq_contains */
 	(binaryfunc)list_inplace_concat,	/* sq_inplace_concat */
 	(ssizeargfunc)list_inplace_repeat,	/* sq_inplace_repeat */
@@ -2470,6 +2470,9 @@
 		if (slicelength <= 0) {
 			return PyList_New(0);
 		}
+		else if (step == 1) {
+			return list_slice(self, start, stop);
+		}
 		else {
 			result = PyList_New(slicelength);
 			if (!result) return NULL;
@@ -2516,6 +2519,12 @@
 		if (step == 1 && ((PySliceObject*)item)->step == Py_None)
 			return list_ass_slice(self, start, stop, value);
 
+		/* Make sure s[5:2] = [..] inserts at the right place:
+		   before 5, not before 2. */
+		if ((step < 0 && start < stop) ||
+		    (step > 0 && start > stop))
+			stop = start;
+
 		if (value == NULL) {
 			/* delete slice */
 			PyObject **garbage;
@@ -2542,7 +2551,7 @@
 			for (cur = start, i = 0;
 			     cur < stop;
 			     cur += step, i++) {
-				Py_ssize_t lim = step;
+				Py_ssize_t lim = step - 1;
 
 				garbage[i] = PyList_GET_ITEM(self, cur);
 
@@ -2554,11 +2563,11 @@
 					self->ob_item + cur + 1,
 					lim * sizeof(PyObject *));
 			}
-
-			for (cur = start + slicelength*step + 1;
-			     cur < self->ob_size; cur++) {
-				PyList_SET_ITEM(self, cur - slicelength,
-						PyList_GET_ITEM(self, cur));
+			cur = start + slicelength*step;
+			if (cur < self->ob_size) {
+				memmove(self->ob_item + cur - slicelength,
+					self->ob_item + cur,
+					(self->ob_size - cur) * sizeof(PyObject *));
 			}
 
 			self->ob_size -= slicelength;

Modified: python/branches/p3yk-noslice/Objects/stringobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/stringobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/stringobject.c	Thu Aug 24 21:27:32 2006
@@ -1290,7 +1290,7 @@
 	(binaryfunc)string_concat, /*sq_concat*/
 	(ssizeargfunc)string_repeat, /*sq_repeat*/
 	(ssizeargfunc)string_item, /*sq_item*/
-	(ssizessizeargfunc)string_slice, /*sq_slice*/
+	0,		/*sq_slice*/
 	0,		/*sq_ass_item*/
 	0,		/*sq_ass_slice*/
 	(objobjproc)string_contains /*sq_contains*/

Modified: python/branches/p3yk-noslice/Objects/structseq.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/structseq.c	(original)
+++ python/branches/p3yk-noslice/Objects/structseq.c	Thu Aug 24 21:27:32 2006
@@ -340,7 +340,7 @@
 	(binaryfunc)structseq_concat,           /* sq_concat */
 	(ssizeargfunc)structseq_repeat,         /* sq_repeat */
 	(ssizeargfunc)structseq_item,		/* sq_item */
-	(ssizessizeargfunc)structseq_slice,	/* sq_slice */
+	0,					/* sq_slice */
 	0,					/* sq_ass_item */
 	0,					/* sq_ass_slice */
 	(objobjproc)structseq_contains,	        /* sq_contains */

Modified: python/branches/p3yk-noslice/Objects/tupleobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/tupleobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/tupleobject.c	Thu Aug 24 21:27:32 2006
@@ -571,7 +571,7 @@
 	(binaryfunc)tupleconcat,		/* sq_concat */
 	(ssizeargfunc)tuplerepeat,		/* sq_repeat */
 	(ssizeargfunc)tupleitem,		/* sq_item */
-	(ssizessizeargfunc)tupleslice,		/* sq_slice */
+	0,					/* sq_slice */
 	0,					/* sq_ass_item */
 	0,					/* sq_ass_slice */
 	(objobjproc)tuplecontains,		/* sq_contains */

Modified: python/branches/p3yk-noslice/Objects/typeobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/typeobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/typeobject.c	Thu Aug 24 21:27:32 2006
@@ -1512,11 +1512,10 @@
 	PyObject *tmp = slots;
 	PyObject *o, *o1;
 	Py_ssize_t i;
-	ssizessizeargfunc copy = slots->ob_type->tp_as_sequence->sq_slice;
 	for (i = 0; i < nslots; i++) {
 		if (PyUnicode_Check(o = PyTuple_GET_ITEM(tmp, i))) {
 			if (tmp == slots) {
-				tmp = copy(slots, 0, PyTuple_GET_SIZE(slots));
+				tmp = PySequence_GetSlice(slots, 0, PyTuple_GET_SIZE(slots));
 				if (tmp == NULL)
 					return NULL;
 			}
@@ -2952,9 +2951,7 @@
 		COPYSEQ(sq_concat);
 		COPYSEQ(sq_repeat);
 		COPYSEQ(sq_item);
-		COPYSEQ(sq_slice);
 		COPYSEQ(sq_ass_item);
-		COPYSEQ(sq_ass_slice);
 		COPYSEQ(sq_contains);
 		COPYSEQ(sq_inplace_concat);
 		COPYSEQ(sq_inplace_repeat);
@@ -3529,22 +3526,6 @@
 	return Py_None;
 }
 
-static PyObject *
-wrap_delslice(PyObject *self, PyObject *args, void *wrapped)
-{
-	ssizessizeobjargproc func = (ssizessizeobjargproc)wrapped;
-	Py_ssize_t i, j;
-	int res;
-
-	if (!PyArg_ParseTuple(args, "nn", &i, &j))
-		return NULL;
-	res = (*func)(self, i, j, NULL);
-	if (res == -1 && PyErr_Occurred())
-		return NULL;
-	Py_INCREF(Py_None);
-	return Py_None;
-}
-
 /* XXX objobjproc is a misnomer; should be objargpred */
 static PyObject *
 wrap_objobjproc(PyObject *self, PyObject *args, void *wrapped)
@@ -4067,8 +4048,6 @@
 	return NULL;
 }
 
-SLOT2(slot_sq_slice, "__getslice__", Py_ssize_t, Py_ssize_t, "nn")
-
 static int
 slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
 {
@@ -4088,24 +4067,6 @@
 }
 
 static int
-slot_sq_ass_slice(PyObject *self, Py_ssize_t i, Py_ssize_t j, PyObject *value)
-{
-	PyObject *res;
-	static PyObject *delslice_str, *setslice_str;
-
-	if (value == NULL)
-		res = call_method(self, "__delslice__", &delslice_str,
-				  "(nn)", i, j);
-	else
-		res = call_method(self, "__setslice__", &setslice_str,
-				  "(nnO)", i, j, value);
-	if (res == NULL)
-		return -1;
-	Py_DECREF(res);
-	return 0;
-}
-
-static int
 slot_sq_contains(PyObject *self, PyObject *value)
 {
 	PyObject *func, *res, *args;
@@ -4810,23 +4771,10 @@
           "x.__rmul__(n) <==> n*x"),
 	SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
 	       "x.__getitem__(y) <==> x[y]"),
-	SQSLOT("__getslice__", sq_slice, slot_sq_slice, wrap_ssizessizeargfunc,
-	       "x.__getslice__(i, j) <==> x[i:j]\n\
-               \n\
-               Use of negative indices is not supported."),
 	SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
 	       "x.__setitem__(i, y) <==> x[i]=y"),
 	SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
 	       "x.__delitem__(y) <==> del x[y]"),
-	SQSLOT("__setslice__", sq_ass_slice, slot_sq_ass_slice,
-	       wrap_ssizessizeobjargproc,
-	       "x.__setslice__(i, j, y) <==> x[i:j]=y\n\
-               \n\
-               Use  of negative indices is not supported."),
-	SQSLOT("__delslice__", sq_ass_slice, slot_sq_ass_slice, wrap_delslice,
-	       "x.__delslice__(i, j) <==> del x[i:j]\n\
-               \n\
-               Use of negative indices is not supported."),
 	SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
 	       "x.__contains__(y) <==> y in x"),
 	SQSLOT("__iadd__", sq_inplace_concat, NULL,

Modified: python/branches/p3yk-noslice/Objects/unicodeobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/unicodeobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/unicodeobject.c	Thu Aug 24 21:27:32 2006
@@ -7054,7 +7054,7 @@
     PyUnicode_Concat,		 	/* sq_concat */
     (ssizeargfunc) unicode_repeat, 	/* sq_repeat */
     (ssizeargfunc) unicode_getitem, 	/* sq_item */
-    (ssizessizeargfunc) unicode_slice, 	/* sq_slice */
+    0,				 	/* sq_slice */
     0, 					/* sq_ass_item */
     0, 					/* sq_ass_slice */
     PyUnicode_Contains, 		/* sq_contains */

Modified: python/branches/p3yk-noslice/Objects/weakrefobject.c
==============================================================================
--- python/branches/p3yk-noslice/Objects/weakrefobject.c	(original)
+++ python/branches/p3yk-noslice/Objects/weakrefobject.c	Thu Aug 24 21:27:32 2006
@@ -525,14 +525,6 @@
 }
 
 static int
-proxy_ass_slice(PyWeakReference *proxy, Py_ssize_t i, Py_ssize_t j, PyObject *value)
-{
-    if (!proxy_checkref(proxy))
-        return -1;
-    return PySequence_SetSlice(PyWeakref_GET_OBJECT(proxy), i, j, value);
-}
-
-static int
 proxy_contains(PyWeakReference *proxy, PyObject *value)
 {
     if (!proxy_checkref(proxy))
@@ -624,9 +616,9 @@
     0,                          /*sq_concat*/
     0,                          /*sq_repeat*/
     0,                          /*sq_item*/
-    (ssizessizeargfunc)proxy_slice, /*sq_slice*/
+    0,                          /*sq_slice*/
     0,                          /*sq_ass_item*/
-    (ssizessizeobjargproc)proxy_ass_slice, /*sq_ass_slice*/
+    0,				 /*sq_ass_slice*/
     (objobjproc)proxy_contains, /* sq_contains */
 };
 

Modified: python/branches/p3yk-noslice/TODO
==============================================================================
--- python/branches/p3yk-noslice/TODO	(original)
+++ python/branches/p3yk-noslice/TODO	Thu Aug 24 21:27:32 2006
@@ -4,12 +4,12 @@
  - Fix compiler-package to avoid SLICE opcodes
  - Add tests for the extended slicing abilities of:
     buffer
-    bytes
     mmap.mmap
     structseq
  - Add extended slicing (or at least slice-object support) to ctypes objects
+ - Make list's mp_[ass_]subscr not depend on list_[ass]slice
  - Remove slice API (or emulate it ontop of sliceobject API)
- - Remove slice/ass_slice PySequenceMethod hooks
+ - Further remove slice/ass_slice PySequenceMethod hooks
  - Figure out what to do with PyMapping_Check (it uses the presence of the
    classic slicing hook to tell sequences-with-extended-slicing from
    mappings.)


More information about the Python-checkins mailing list