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.)