From 50d756e262fc6804336e5a624aee0d885a195973 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Sat, 18 Aug 2001 17:43:36 +0000 Subject: [PATCH] Fix SF bug #443600: 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. --- Python/ceval.c | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index d3898fb733..f052e9726a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3347,30 +3347,61 @@ _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] */ { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return NULL; - if (!_PyEval_SliceIndex(w, &ihigh)) - return NULL; - return PySequence_GetSlice(u, ilow, ihigh); + 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; + if (!_PyEval_SliceIndex(w, &ihigh)) + 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 */ { - int ilow = 0, ihigh = INT_MAX; - if (!_PyEval_SliceIndex(v, &ilow)) - return -1; - if (!_PyEval_SliceIndex(w, &ihigh)) - return -1; - if (x == NULL) - return PySequence_DelSlice(u, ilow, ihigh); - else - return PySequence_SetSlice(u, ilow, ihigh, 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; + if (!_PyEval_SliceIndex(w, &ihigh)) + return -1; + if (x == NULL) + return PySequence_DelSlice(u, ilow, ihigh); + 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 * -- 2.40.0