Apply SF patch #101029: call __getitem__ with a proper slice object if there

is no __getslice__ available. Also does the same for C extension types.
Includes rudimentary documentation (it could use a cross reference to the
section on slice objects, I couldn't figure out how to do that) and a test
suite for all Python __hooks__ I could think of, including the new
behaviour.
This commit is contained in:
Thomas Wouters 2000-08-17 22:37:32 +00:00
parent 68add2e938
commit 1d75a79c00
5 changed files with 435 additions and 18 deletions

View file

@ -876,10 +876,29 @@ PySequence_GetItem(PyObject *s, int i)
return type_error("unindexable object");
}
static PyObject *
sliceobj_from_intint(int i, int j)
{
PyObject *start, *end, *slice;
start = PyInt_FromLong((long)i);
if (!start)
return NULL;
end = PyInt_FromLong((long)j);
if (!end) {
Py_DECREF(start);
return NULL;
}
slice = PySlice_New(start, end, NULL);
Py_DECREF(start);
Py_DECREF(end);
return slice;
}
PyObject *
PySequence_GetSlice(PyObject *s, int i1, int i2)
{
PySequenceMethods *m;
PyMappingMethods *mp;
if (!s) return null_error();
@ -897,6 +916,14 @@ PySequence_GetSlice(PyObject *s, int i1, int i2)
}
}
return m->sq_slice(s, i1, i2);
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
PyObject *res;
PyObject *slice = sliceobj_from_intint(i1, i2);
if (!slice)
return NULL;
res = mp->mp_subscript(s, slice);
Py_DECREF(slice);
return res;
}
return type_error("unsliceable object");
@ -960,6 +987,7 @@ int
PySequence_SetSlice(PyObject *s, int i1, int i2, PyObject *o)
{
PySequenceMethods *m;
PyMappingMethods *mp;
if (s == NULL) {
null_error();
@ -980,7 +1008,16 @@ PySequence_SetSlice(PyObject *s, int i1, int i2, PyObject *o)
}
}
return m->sq_ass_slice(s, i1, i2, o);
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
int res;
PyObject *slice = sliceobj_from_intint(i1, i2);
if (!slice)
return -1;
res = mp->mp_ass_subscript(s, slice, o);
Py_DECREF(slice);
return res;
}
type_error("object doesn't support slice assignment");
return -1;
}

View file

@ -971,6 +971,27 @@ instance_item(PyInstanceObject *inst, int i)
return res;
}
static PyObject *
sliceobj_from_intint(int i, int j)
{
PyObject *start, *end, *res;
start = PyInt_FromLong((long)i);
if (!start)
return NULL;
end = PyInt_FromLong((long)j);
if (!end) {
Py_DECREF(start);
return NULL;
}
res = PySlice_New(start, end, NULL);
Py_DECREF(start);
Py_DECREF(end);
return res;
}
static PyObject *
instance_slice(PyInstanceObject *inst, int i, int j)
{
@ -980,9 +1001,19 @@ instance_slice(PyInstanceObject *inst, int i, int j)
if (getslicestr == NULL)
getslicestr = PyString_InternFromString("__getslice__");
func = instance_getattr(inst, getslicestr);
if (func == NULL)
return NULL;
arg = Py_BuildValue("(ii)", i, j);
if (func == NULL) {
PyErr_Clear();
if (getitemstr == NULL)
getitemstr = PyString_InternFromString("__getitem__");
func = instance_getattr(inst, getitemstr);
if (func == NULL)
return NULL;
arg = Py_BuildValue("(N)", sliceobj_from_intint(i, j));
} else
arg = Py_BuildValue("(ii)", i, j);
if (arg == NULL) {
Py_DECREF(func);
return NULL;
@ -1038,19 +1069,39 @@ instance_ass_slice(PyInstanceObject *inst, int i, int j, PyObject *value)
delslicestr =
PyString_InternFromString("__delslice__");
func = instance_getattr(inst, delslicestr);
if (func == NULL) {
PyErr_Clear();
if (delitemstr == NULL)
delitemstr =
PyString_InternFromString("__delitem__");
func = instance_getattr(inst, delitemstr);
if (func == NULL)
return -1;
arg = Py_BuildValue("(N)",
sliceobj_from_intint(i, j));
} else
arg = Py_BuildValue("(ii)", i, j);
}
else {
if (setslicestr == NULL)
setslicestr =
PyString_InternFromString("__setslice__");
func = instance_getattr(inst, setslicestr);
if (func == NULL) {
PyErr_Clear();
if (setitemstr == NULL)
setitemstr =
PyString_InternFromString("__setitem__");
func = instance_getattr(inst, setitemstr);
if (func == NULL)
return -1;
arg = Py_BuildValue("(NO)",
sliceobj_from_intint(i, j), value);
} else
arg = Py_BuildValue("(iiO)", i, j, value);
}
if (func == NULL)
return -1;
if (value == NULL)
arg = Py_BuildValue("(ii)", i, j);
else
arg = Py_BuildValue("(iiO)", i, j, value);
if (arg == NULL) {
Py_DECREF(func);
return -1;