Change to get/set/del slice operations so that if the object doesn't
support slicing, *or* if either of the slice arguments is not an int
or long, we construct a slice object and call the get/set/del item
operation instead.  This makes it possible to design classes that
support slice arguments of non-integral types.
This commit is contained in:
Guido van Rossum 2001-08-18 17:43:36 +00:00
parent b60f2d0977
commit 50d756e262
1 changed files with 46 additions and 15 deletions

View File

@ -3347,9 +3347,16 @@ _PyEval_SliceIndex(PyObject *v, int *pi)
return 1;
}
#undef ISINT
#define ISINT(x) ((x) == NULL || PyInt_Check(x) || PyLong_Check(x))
static PyObject *
apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
{
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
int ilow = 0, ihigh = INT_MAX;
if (!_PyEval_SliceIndex(v, &ilow))
return NULL;
@ -3357,11 +3364,23 @@ apply_slice(PyObject *u, PyObject *v, PyObject *w) /* return u[v:w] */
return NULL;
return PySequence_GetSlice(u, ilow, ihigh);
}
else {
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL)
return PyObject_GetItem(u, slice);
else
return NULL;
}
}
static int
assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
/* u[v:w] = x */
{
PyTypeObject *tp = u->ob_type;
PySequenceMethods *sq = tp->tp_as_sequence;
if (sq && sq->sq_slice && ISINT(v) && ISINT(w)) {
int ilow = 0, ihigh = INT_MAX;
if (!_PyEval_SliceIndex(v, &ilow))
return -1;
@ -3372,6 +3391,18 @@ assign_slice(PyObject *u, PyObject *v, PyObject *w, PyObject *x)
else
return PySequence_SetSlice(u, ilow, ihigh, x);
}
else {
PyObject *slice = PySlice_New(v, w, NULL);
if (slice != NULL) {
if (x != NULL)
return PyObject_SetItem(u, slice, x);
else
return PyObject_DelItem(u, slice);
}
else
return -1;
}
}
static PyObject *
cmp_outcome(int op, register PyObject *v, register PyObject *w)