]> granicus.if.org Git - python/commitdiff
A few days ago, Guido said (in the thread "[Python-Dev] Python
authorMichael W. Hudson <mwh@python.net>
Fri, 19 Jul 2002 15:47:06 +0000 (15:47 +0000)
committerMichael W. Hudson <mwh@python.net>
Fri, 19 Jul 2002 15:47:06 +0000 (15:47 +0000)
version of PySlice_GetIndicesEx"):

> OK.  Michael, if you want to check in indices(), go ahead.

Then I did what was needed, but didn't check it in.  Here it is.

Doc/ref/ref3.tex
Lib/test/test_slice.py [new file with mode: 0644]
Objects/sliceobject.c

index d719db31d0d6fb706c22213f52d07d5baea393cc..9f8d2626c9d1c29a7af906bf58b04d8214c9835d 100644 (file)
@@ -892,6 +892,15 @@ Special read-only attributes: \member{start} is the lower bound;
   \ttindex{stop}
   \ttindex{step}}
 
+Special method: \method{indices} takes an single integer argument
+\var{length} and computes information about the extended slice that
+the slice object would describe if applied to a sequence of
+\var{length}.  It returns a tuple of three integers; respectively
+these are the \var{start} and \var{stop} indices and the \var{step} or
+stride length of the slice.  Missing or out-of-bounds indices are
+handled in a manner consistent with regular slices.
+\versionadded{2.3}
+
 \end{description} % Internal types
 
 \end{description} % Types
diff --git a/Lib/test/test_slice.py b/Lib/test/test_slice.py
new file mode 100644 (file)
index 0000000..895238f
--- /dev/null
@@ -0,0 +1,14 @@
+# tests for slice objects; in particular the indices method.
+
+from test_support import vereq
+
+vereq(slice(None           ).indices(10), (0, 10,  1))
+vereq(slice(None,  None,  2).indices(10), (0, 10,  2))
+vereq(slice(1,     None,  2).indices(10), (1, 10,  2))
+vereq(slice(None,  None, -1).indices(10), (9, -1, -1))
+vereq(slice(None,  None, -2).indices(10), (9, -1, -2))
+vereq(slice(3,     None, -2).indices(10), (3, -1, -2))
+vereq(slice(-100,  100     ).indices(10), slice(None).indices(10))
+vereq(slice(100,  -100,  -1).indices(10), slice(None, None, -1).indices(10))
+vereq(slice(-100L, 100L, 2L).indices(10), (0, 10,  2))
+
index a43644d18fa3350acde6d14ea51dbbc50cd57143..f2d84dad65d005fd90b346782c67215cc2ebb336 100644 (file)
@@ -221,6 +221,39 @@ static PyMemberDef slice_members[] = {
        {0}
 };
 
+static PyObject*
+slice_indices(PySliceObject* self, PyObject* len)
+{
+       int ilen, start, stop, step, slicelength;
+
+       ilen = PyInt_AsLong(len);
+
+       if (ilen == -1 && PyErr_Occurred()) {
+               return NULL;
+       }
+
+       if (PySlice_GetIndicesEx(self, ilen, &start, &stop, 
+                                &step, &slicelength) < 0) {
+               return NULL;
+       }
+
+       return Py_BuildValue("(lll)", start, stop, step);
+}
+
+PyDoc_STRVAR(slice_indices_doc,
+"S.indices(len) -> (start, stop, stride)\n\
+\n\
+Assuming a sequence of length len, calculate the start and stop\n\
+indices, and the stride length of the extended slice described by\n\
+S. Out of bounds indices are clipped in a manner consistent with the\n\
+handling of normal slices.");
+
+static PyMethodDef slice_methods[] = {
+       {"indices",     (PyCFuntion)slice_indices,
+        METH_O,        slice_indices_doc},
+       {NULL, NULL}
+};
+
 static int
 slice_compare(PySliceObject *v, PySliceObject *w)
 {
@@ -271,7 +304,7 @@ PyTypeObject PySlice_Type = {
        0,                                      /* tp_weaklistoffset */
        0,                                      /* tp_iter */
        0,                                      /* tp_iternext */
-       0,                                      /* tp_methods */
+       slice_methods,                          /* tp_methods */
        slice_members,                          /* tp_members */
        0,                                      /* tp_getset */
        0,                                      /* tp_base */