]> granicus.if.org Git - python/commitdiff
Fix SF bug #443600:
authorGuido van Rossum <guido@python.org>
Sat, 18 Aug 2001 17:43:36 +0000 (17:43 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 18 Aug 2001 17:43:36 +0000 (17:43 +0000)
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

index d3898fb7336d6b9c41bbc4af4eb7aba21a483a61..f052e9726aff7ee1f9ceda960c7639e0cf873085 100644 (file)
@@ -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 *