[Python-checkins] python/dist/src/Objects listobject.c,2.108,2.109 sliceobject.c,2.12,2.13 stringobject.c,2.165,2.166 tupleobject.c,2.64,2.65 unicodeobject.c,2.151,2.152
mwh@users.sourceforge.net
mwh@users.sourceforge.net
Tue, 11 Jun 2002 03:55:14 -0700
- Previous message: [Python-checkins] python/dist/src/Misc NEWS,1.422,1.423
- Next message: [Python-checkins] python/dist/src/Objects listobject.c,2.108,2.109
sliceobject.c,2.12,2.13 stringobject.c,2.165,2.166
tupleobject.c,2.64,2.65 unicodeobject.c,2.151,2.152
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv9709/Objects
Modified Files:
listobject.c sliceobject.c stringobject.c tupleobject.c
unicodeobject.c
Log Message:
This is my nearly two year old patch
[ 400998 ] experimental support for extended slicing on lists
somewhat spruced up and better tested than it was when I wrote it.
Includes docs & tests. The whatsnew section needs expanding, and arrays
should support extended slices -- later.
Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.108
retrieving revision 2.109
diff -C2 -d -r2.108 -r2.109
*** listobject.c 1 Jun 2002 05:22:55 -0000 2.108
--- listobject.c 11 Jun 2002 10:55:11 -0000 2.109
***************
*** 1685,1688 ****
--- 1685,1874 ----
staticforward PyObject * list_iter(PyObject *seq);
+ static PyObject*
+ list_subscript(PyListObject* self, PyObject* item)
+ {
+ if (PyInt_Check(item)) {
+ long i = PyInt_AS_LONG(item);
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_item(self, i);
+ }
+ else if (PyLong_Check(item)) {
+ long i = PyLong_AsLong(item);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ int start, stop, step, slicelength, cur, i;
+ PyObject* result;
+ PyObject* it;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyList_New(0);
+ }
+ else {
+ result = PyList_New(slicelength);
+ if (!result) return NULL;
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ it = PyList_GET_ITEM(self, cur);
+ Py_INCREF(it);
+ PyList_SET_ITEM(result, i, it);
+ }
+
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "list indices must be integers");
+ return NULL;
+ }
+ }
+
+ static int
+ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value)
+ {
+ if (PyInt_Check(item)) {
+ long i = PyInt_AS_LONG(item);
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_ass_item(self, i, value);
+ }
+ else if (PyLong_Check(item)) {
+ long i = PyLong_AsLong(item);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += PyList_GET_SIZE(self);
+ return list_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ int start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, self->ob_size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+
+ if (value == NULL) {
+ /* delete slice */
+ PyObject **garbage, **item;
+ int cur, i, j;
+
+ if (slicelength <= 0)
+ return 0;
+
+ if (step < 0) {
+ stop = start + 1;
+ start = stop + step*(slicelength - 1) - 1;
+ step = -step;
+ }
+
+ garbage = (PyObject**)
+ PyMem_MALLOC(slicelength*sizeof(PyObject*));
+
+ /* drawing pictures might help
+ understand these for loops */
+ for (cur = start, i = 0; cur < stop; cur += step, i++) {
+ garbage[i] = PyList_GET_ITEM(self, cur);
+
+ for (j = 0; j < step; j++) {
+ PyList_SET_ITEM(self, cur + j - i,
+ PyList_GET_ITEM(self, cur + j + 1));
+ }
+ }
+ for (cur = start + slicelength*step + 1;
+ cur < self->ob_size; cur++) {
+ PyList_SET_ITEM(self, cur - slicelength,
+ PyList_GET_ITEM(self, cur));
+ }
+ self->ob_size -= slicelength;
+ item = self->ob_item;
+ NRESIZE(item, PyObject*, self->ob_size);
+ self->ob_item = item;
+
+ for (i = 0; i < slicelength; i++) {
+ Py_DECREF(garbage[i]);
+ }
+ PyMem_FREE(garbage);
+
+ return 0;
+ }
+ else {
+ /* assign slice */
+ PyObject **garbage, *ins;
+ int cur, i;
+
+ if (!PyList_Check(value)) {
+ PyErr_Format(PyExc_TypeError,
+ "must assign list (not \"%.200s\") to slice",
+ value->ob_type->tp_name);
+ return -1;
+ }
+
+ if (PyList_GET_SIZE(value) != slicelength) {
+ PyErr_Format(PyExc_ValueError,
+ "attempt to assign list of size %d to extended slice of size %d",
+ PyList_Size(value), slicelength);
+ return -1;
+ }
+
+ if (!slicelength)
+ return 0;
+
+ /* protect against a[::-1] = a */
+ if (self == (PyListObject*)value) {
+ value = list_slice((PyListObject*)value, 0,
+ PyList_GET_SIZE(value));
+ }
+ else {
+ Py_INCREF(value);
+ }
+
+ garbage = (PyObject**)
+ PyMem_MALLOC(slicelength*sizeof(PyObject*));
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ garbage[i] = PyList_GET_ITEM(self, cur);
+
+ ins = PyList_GET_ITEM(value, i);
+ Py_INCREF(ins);
+ PyList_SET_ITEM(self, cur, ins);
+ }
+
+ for (i = 0; i < slicelength; i++) {
+ Py_DECREF(garbage[i]);
+ }
+
+ PyMem_FREE(garbage);
+ Py_DECREF(value);
+
+ return 0;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "list indices must be integers");
+ return -1;
+ }
+ }
+
+ static PyMappingMethods list_as_mapping = {
+ (inquiry)list_length,
+ (binaryfunc)list_subscript,
+ (objobjargproc)list_ass_subscript
+ };
+
PyTypeObject PyList_Type = {
PyObject_HEAD_INIT(&PyType_Type)
***************
*** 1699,1703 ****
0, /* tp_as_number */
&list_as_sequence, /* tp_as_sequence */
! 0, /* tp_as_mapping */
list_nohash, /* tp_hash */
0, /* tp_call */
--- 1885,1889 ----
0, /* tp_as_number */
&list_as_sequence, /* tp_as_sequence */
! &list_as_mapping, /* tp_as_mapping */
list_nohash, /* tp_hash */
0, /* tp_call */
Index: sliceobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v
retrieving revision 2.12
retrieving revision 2.13
diff -C2 -d -r2.12 -r2.13
*** sliceobject.c 12 Apr 2002 03:04:15 -0000 2.12
--- sliceobject.c 11 Jun 2002 10:55:11 -0000 2.13
***************
*** 110,113 ****
--- 110,166 ----
}
+ int
+ PySlice_GetIndicesEx(PySliceObject *r, int length,
+ int *start, int *stop, int *step, int *slicelength)
+ {
+ /* this is harder to get right than you might think */
+ int defstart, defstop;
+
+ if (r->step == Py_None) {
+ *step = 1;
+ } else {
+ *step = PyInt_AsLong(r->step);
+ if (*step == -1 && PyErr_Occurred()) {
+ return -1;
+ }
+ else if (*step == 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "slice step cannot be zero");
+ return -1;
+ }
+ }
+
+ defstart = *step < 0 ? length-1 : 0;
+ defstop = *step < 0 ? -1 : length;
+
+ if (r->start == Py_None) {
+ *start = defstart;
+ } else {
+ if (!_PyEval_SliceIndex(r->start, start)) return -1;
+ if (*start < 0) *start += length;
+ if (*start < 0) *start = (*step < 0) ? -1 : 0;
+ if (*start >= length)
+ *start = (*step < 0) ? length - 1 : length;
+ }
+
+ if (r->stop == Py_None) {
+ *stop = defstop;
+ } else {
+ if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
+ if (*stop < 0) *stop += length;
+ if (*stop < 0) *stop = -1;
+ if (*stop > length) *stop = length;
+ }
+
+ if (*step < 0) {
+ *slicelength = (*stop-*start+1)/(*step)+1;
+ } else {
+ *slicelength = (*stop-*start-1)/(*step)+1;
+ }
+ if (*slicelength < 0) *slicelength = 0;
+
+ return 0;
+ }
+
static void
slice_dealloc(PySliceObject *r)
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.165
retrieving revision 2.166
diff -C2 -d -r2.165 -r2.166
*** stringobject.c 31 May 2002 19:58:01 -0000 2.165
--- stringobject.c 11 Jun 2002 10:55:11 -0000 2.166
***************
*** 941,944 ****
--- 941,998 ----
}
+ static PyObject*
+ string_subscript(PyStringObject* self, PyObject* item)
+ {
+ if (PyInt_Check(item)) {
+ long i = PyInt_AS_LONG(item);
+ if (i < 0)
+ i += PyString_GET_SIZE(self);
+ return string_item(self,i);
+ }
+ else if (PyLong_Check(item)) {
+ long i = PyLong_AsLong(item);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyString_GET_SIZE(self);
+ return string_item(self,i);
+ }
+ else if (PySlice_Check(item)) {
+ int start, stop, step, slicelength, cur, i;
+ char* source_buf;
+ char* result_buf;
+ PyObject* result;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item,
+ PyString_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyString_FromStringAndSize("", 0);
+ }
+ else {
+ source_buf = PyString_AsString((PyObject*)self);
+ result_buf = PyMem_Malloc(slicelength);
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+
+ result = PyString_FromStringAndSize(result_buf,
+ slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "string indices must be integers");
+ return NULL;
+ }
+ }
+
static int
string_buffer_getreadbuf(PyStringObject *self, int index, const void **ptr)
***************
*** 992,995 ****
--- 1046,1055 ----
};
+ static PyMappingMethods string_as_mapping = {
+ (inquiry)string_length,
+ (binaryfunc)string_subscript,
+ 0,
+ };
+
static PyBufferProcs string_as_buffer = {
(getreadbufferproc)string_buffer_getreadbuf,
***************
*** 2930,2934 ****
0, /* tp_as_number */
&string_as_sequence, /* tp_as_sequence */
! 0, /* tp_as_mapping */
(hashfunc)string_hash, /* tp_hash */
0, /* tp_call */
--- 2990,2994 ----
0, /* tp_as_number */
&string_as_sequence, /* tp_as_sequence */
! &string_as_mapping, /* tp_as_mapping */
(hashfunc)string_hash, /* tp_hash */
0, /* tp_call */
***************
*** 3350,3354 ****
argidx = -2;
}
! if (args->ob_type->tp_as_mapping)
dict = args;
while (--fmtcnt >= 0) {
--- 3410,3414 ----
argidx = -2;
}
! if (args->ob_type->tp_as_mapping && !PyTuple_Check(args))
dict = args;
while (--fmtcnt >= 0) {
Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.64
retrieving revision 2.65
diff -C2 -d -r2.64 -r2.65
*** tupleobject.c 12 Apr 2002 03:05:52 -0000 2.64
--- tupleobject.c 11 Jun 2002 10:55:12 -0000 2.65
***************
*** 542,545 ****
--- 542,602 ----
};
+ static PyObject*
+ tuplesubscript(PyTupleObject* self, PyObject* item)
+ {
+ if (PyInt_Check(item)) {
+ long i = PyInt_AS_LONG(item);
+ if (i < 0)
+ i += PyTuple_GET_SIZE(self);
+ return tupleitem(self, i);
+ }
+ else if (PyLong_Check(item)) {
+ long i = PyLong_AsLong(item);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyTuple_GET_SIZE(self);
+ return tupleitem(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ int start, stop, step, slicelength, cur, i;
+ PyObject* result;
+ PyObject* it;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item,
+ PyTuple_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else {
+ result = PyTuple_New(slicelength);
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ it = PyTuple_GET_ITEM(self, cur);
+ Py_INCREF(it);
+ PyTuple_SET_ITEM(result, i, it);
+ }
+
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "tuple indices must be integers");
+ return NULL;
+ }
+ }
+
+ static PyMappingMethods tuple_as_mapping = {
+ (inquiry)tuplelength,
+ (binaryfunc)tuplesubscript,
+ 0
+ };
+
PyTypeObject PyTuple_Type = {
PyObject_HEAD_INIT(&PyType_Type)
***************
*** 556,560 ****
0, /* tp_as_number */
&tuple_as_sequence, /* tp_as_sequence */
! 0, /* tp_as_mapping */
(hashfunc)tuplehash, /* tp_hash */
0, /* tp_call */
--- 613,617 ----
0, /* tp_as_number */
&tuple_as_sequence, /* tp_as_sequence */
! &tuple_as_mapping, /* tp_as_mapping */
(hashfunc)tuplehash, /* tp_hash */
0, /* tp_call */
Index: unicodeobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v
retrieving revision 2.151
retrieving revision 2.152
diff -C2 -d -r2.151 -r2.152
*** unicodeobject.c 29 May 2002 13:46:29 -0000 2.151
--- unicodeobject.c 11 Jun 2002 10:55:12 -0000 2.152
***************
*** 5062,5065 ****
--- 5062,5117 ----
};
+ static PyObject*
+ unicode_subscript(PyUnicodeObject* self, PyObject* item)
+ {
+ if (PyInt_Check(item)) {
+ long i = PyInt_AS_LONG(item);
+ if (i < 0)
+ i += PyString_GET_SIZE(self);
+ return unicode_getitem(self, i);
+ } else if (PyLong_Check(item)) {
+ long i = PyLong_AsLong(item);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += PyString_GET_SIZE(self);
+ return unicode_getitem(self, i);
+ } else if (PySlice_Check(item)) {
+ int start, stop, step, slicelength, cur, i;
+ Py_UNICODE* source_buf;
+ Py_UNICODE* result_buf;
+ PyObject* result;
+
+ if (PySlice_GetIndicesEx((PySliceObject*)item, PyString_GET_SIZE(self),
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
+
+ if (slicelength <= 0) {
+ return PyUnicode_FromUnicode(NULL, 0);
+ } else {
+ source_buf = PyUnicode_AS_UNICODE((PyObject*)self);
+ result_buf = PyMem_MALLOC(slicelength*sizeof(Py_UNICODE));
+
+ for (cur = start, i = 0; i < slicelength; cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
+
+ result = PyUnicode_FromUnicode(result_buf, slicelength);
+ PyMem_FREE(result_buf);
+ return result;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError, "string indices must be integers");
+ return NULL;
+ }
+ }
+
+ static PyMappingMethods unicode_as_mapping = {
+ (inquiry)unicode_length, /* mp_length */
+ (binaryfunc)unicode_subscript, /* mp_subscript */
+ (objobjargproc)0, /* mp_ass_subscript */
+ };
+
static int
unicode_buffer_getreadbuf(PyUnicodeObject *self,
***************
*** 5356,5360 ****
argidx = -2;
}
! if (args->ob_type->tp_as_mapping)
dict = args;
--- 5408,5412 ----
argidx = -2;
}
! if (args->ob_type->tp_as_mapping && !PyTuple_Check(args))
dict = args;
***************
*** 5818,5822 ****
0, /* tp_as_number */
&unicode_as_sequence, /* tp_as_sequence */
! 0, /* tp_as_mapping */
(hashfunc) unicode_hash, /* tp_hash*/
0, /* tp_call*/
--- 5870,5874 ----
0, /* tp_as_number */
&unicode_as_sequence, /* tp_as_sequence */
! &unicode_as_mapping, /* tp_as_mapping */
(hashfunc) unicode_hash, /* tp_hash*/
0, /* tp_call*/
- Previous message: [Python-checkins] python/dist/src/Misc NEWS,1.422,1.423
- Next message: [Python-checkins] python/dist/src/Objects listobject.c,2.108,2.109
sliceobject.c,2.12,2.13 stringobject.c,2.165,2.166
tupleobject.c,2.64,2.65 unicodeobject.c,2.151,2.152
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]