summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-08-18 17:43:36 (GMT)
committerGuido van Rossum <guido@python.org>2001-08-18 17:43:36 (GMT)
commit50d756e262fc6804336e5a624aee0d885a195973 (patch)
tree09a1397adc797a5cf28bbb5c4cdbd82a899bcdf7 /Python
parentb60f2d0977323d50e521718301f962ed40e88d69 (diff)
downloadcpython-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.c61
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 *