diff options
author | Guido van Rossum <guido@python.org> | 2001-08-18 17:43:36 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-08-18 17:43:36 (GMT) |
commit | 50d756e262fc6804336e5a624aee0d885a195973 (patch) | |
tree | 09a1397adc797a5cf28bbb5c4cdbd82a899bcdf7 /Python | |
parent | b60f2d0977323d50e521718301f962ed40e88d69 (diff) | |
download | cpython-50d756e262fc6804336e5a624aee0d885a195973.zip cpython-50d756e262fc6804336e5a624aee0d885a195973.tar.gz cpython-50d756e262fc6804336e5a624aee0d885a195973.tar.bz2 |
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.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index d3898fb..f052e97 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 * |