]> granicus.if.org Git - python/commitdiff
Added optional None arguments to itertools.islice().
authorRaymond Hettinger <python@rcn.com>
Sun, 5 Dec 2004 09:25:51 +0000 (09:25 +0000)
committerRaymond Hettinger <python@rcn.com>
Sun, 5 Dec 2004 09:25:51 +0000 (09:25 +0000)
Doc/lib/libitertools.tex
Lib/test/test_itertools.py
Misc/NEWS
Modules/itertoolsmodule.c

index be53015f7cd979020b7a134aaab93c8068d54e9b..fbde69dad1045d3e5e4b87bfd53d5a2084066253 100644 (file)
@@ -261,6 +261,11 @@ by functions or loops that truncate the stream.
              yield element
              next += step             
   \end{verbatim}
+
+  If \var{start} is \code{None}, then iteration starts at zero.
+  If \var{step} is \code{None}, then the step defaults to one.
+  \versionchanged[accept \code{None} values for default \var{start} and
+                  \var{step}]{2.5}
 \end{funcdesc}
 
 \begin{funcdesc}{izip}{*iterables}
index 0f74c6207359c968699438f57c907dbf64008c9b..becb3b2088e610f55ea3b6a787489d1429d47c20 100644 (file)
@@ -260,6 +260,8 @@ class TestBasicOps(unittest.TestCase):
 
         # Test stop=None
         self.assertEqual(list(islice(xrange(10), None)), range(10))
+        self.assertEqual(list(islice(xrange(10), None, None)), range(10))
+        self.assertEqual(list(islice(xrange(10), None, None, None)), range(10))
         self.assertEqual(list(islice(xrange(10), 2, None)), range(2, 10))
         self.assertEqual(list(islice(xrange(10), 1, None, 2)), range(1, 10, 2))
 
index 235c257dbdde4c3a6d4c096c7c475ea9b992e962..95b9d2c7a15b8149691d8712af51b3d2ccf95685 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -17,6 +17,10 @@ Core and builtins
 Extension Modules
 -----------------
 
+- itertools.islice() now accepts None for the start and step arguments.
+  This allows islice() to work more readily with slices:
+      islice(s.start, s.stop, s.step)
+
 
 Library
 -------
index bf148ac2441bfffdd07d752d33b1ddb0dab90d64..31ba13a3ad6dbab91290c025469a34e75fb3c8e3 100644 (file)
@@ -1044,14 +1044,14 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
        PyObject *seq;
        long start=0, stop=-1, step=1;
-       PyObject *it, *a1=NULL, *a2=NULL;
+       PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
        int numargs;
        isliceobject *lz;
 
-       numargs = PyTuple_Size(args);
-       if (!PyArg_ParseTuple(args, "OO|Ol:islice", &seq, &a1, &a2, &step))
+       if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
                return NULL;
 
+       numargs = PyTuple_Size(args);
        if (numargs == 2) {
                if (a1 != Py_None) {
                        stop = PyInt_AsLong(a1);
@@ -1059,39 +1059,41 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
                                if (PyErr_Occurred())
                                        PyErr_Clear();
                                PyErr_SetString(PyExc_ValueError,
-                                  "Stop argument must be a non-negative integer or None.");
+                                  "Stop argument for islice() must be a non-negative integer or None.");
                                return NULL;
                        }
                }
        } else {
-               start = PyInt_AsLong(a1);
-               if (start == -1 && PyErr_Occurred()) {
+               if (a1 != Py_None)
+                       start = PyInt_AsLong(a1);
+               if (start == -1 && PyErr_Occurred())
                        PyErr_Clear();
-                       PyErr_SetString(PyExc_ValueError,
-                          "Start argument must be a non-negative integer.");
-                       return NULL;
-               }
                if (a2 != Py_None) {
                        stop = PyInt_AsLong(a2);
                        if (stop == -1) {
                                if (PyErr_Occurred())
                                        PyErr_Clear();
                                PyErr_SetString(PyExc_ValueError,
-                                  "Stop argument must be a non-negative integer or None.");
+                                  "Stop argument for islice() must be a non-negative integer or None.");
                                return NULL;
                        }
                }
        }
-
        if (start<0 || stop<-1) {
                PyErr_SetString(PyExc_ValueError,
-                  "Indices for islice() must be non-negative integers.");
+                  "Indices for islice() must be non-negative integers or None.");
                return NULL;
        }
 
+       if (a3 != NULL) {
+               if (a3 != Py_None)
+                       step = PyInt_AsLong(a3);
+               if (step == -1 && PyErr_Occurred())
+                       PyErr_Clear();
+       }
        if (step<1) {
                PyErr_SetString(PyExc_ValueError,
-                  "Step must be one or larger for islice().");
+                  "Step for islice() must be a positive integer or None.");
                return NULL;
        }