mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
b6cc7d2806
commit
f0d777c56b
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue