From: Michael W. Hudson Date: Fri, 19 Jul 2002 15:47:06 +0000 (+0000) Subject: A few days ago, Guido said (in the thread "[Python-Dev] Python X-Git-Tag: v2.3c1~4930 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f0d777c56b710f68c96582c10b49d83b5ad7d32d;p=python A few days ago, Guido said (in the thread "[Python-Dev] Python 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. --- diff --git a/Doc/ref/ref3.tex b/Doc/ref/ref3.tex index d719db31d0..9f8d2626c9 100644 --- a/Doc/ref/ref3.tex +++ b/Doc/ref/ref3.tex @@ -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 index 0000000000..895238f106 --- /dev/null +++ b/Lib/test/test_slice.py @@ -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)) + diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index a43644d18f..f2d84dad65 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -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 */