diff options
author | Georg Brandl <georg@python.org> | 2008-05-13 19:04:54 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2008-05-13 19:04:54 (GMT) |
commit | 913835763a4734097423c49e284ce8d4b1093917 (patch) | |
tree | 500df9f02e13104b9c00d9f07541ab324abc1a29 | |
parent | ef9764f1a479808b340c16bcfdb0cd6838465ea9 (diff) | |
download | cpython-913835763a4734097423c49e284ce8d4b1093917.zip cpython-913835763a4734097423c49e284ce8d4b1093917.tar.gz cpython-913835763a4734097423c49e284ce8d4b1093917.tar.bz2 |
#2831: add start argument to enumerate(). Patch by Scott Dial and me.
-rw-r--r-- | Doc/library/functions.rst | 12 | ||||
-rw-r--r-- | Lib/test/test_enumerate.py | 16 | ||||
-rw-r--r-- | Objects/enumobject.c | 28 |
3 files changed, 45 insertions, 11 deletions
diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index bc07d84..6de9392 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -335,15 +335,15 @@ available. They are listed here in alphabetical order. Using :func:`divmod` with complex numbers is deprecated. -.. function:: enumerate(sequence) +.. function:: enumerate(sequence[, start=0]) Return an enumerate object. *sequence* must be a sequence, an :term:`iterator`, or some other object which supports iteration. The :meth:`next` method of the iterator returned by :func:`enumerate` returns a - tuple containing a count (from zero) and the corresponding value obtained - from iterating over *iterable*. :func:`enumerate` is useful for obtaining an - indexed series: ``(0, seq[0])``, ``(1, seq[1])``, ``(2, seq[2])``, .... For - example: + tuple containing a count (from *start* which defaults to 0) and the + corresponding value obtained from iterating over *iterable*. + :func:`enumerate` is useful for obtaining an indexed series: ``(0, seq[0])``, + ``(1, seq[1])``, ``(2, seq[2])``, .... For example: >>> for i, season in enumerate(['Spring', 'Summer', 'Fall', 'Winter']): ... print i, season @@ -353,6 +353,8 @@ available. They are listed here in alphabetical order. 3 Winter .. versionadded:: 2.3 + .. versionadded:: 2.6 + The *start* parameter. .. function:: eval(expression[, globals[, locals]]) diff --git a/Lib/test/test_enumerate.py b/Lib/test/test_enumerate.py index e0a272e..a27846f 100644 --- a/Lib/test/test_enumerate.py +++ b/Lib/test/test_enumerate.py @@ -100,7 +100,8 @@ class EnumerateTestCase(unittest.TestCase): def test_argumentcheck(self): self.assertRaises(TypeError, self.enum) # no arguments self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable) - self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments + self.assertRaises(TypeError, self.enum, 'abc', 'a') # wrong type + self.assertRaises(TypeError, self.enum, 'abc', 2, 3) # too many arguments def test_tuple_reuse(self): # Tests an implementation detail where tuple is reused @@ -196,6 +197,19 @@ class TestReversed(unittest.TestCase): self.assertEqual(rc, sys.getrefcount(r)) +class TestStart(EnumerateTestCase): + + enum = lambda i: enumerate(i, start=11) + seq, res = 'abc', [(1, 'a'), (2, 'b'), (3, 'c')] + + +class TestLongStart(EnumerateTestCase): + + enum = lambda i: enumerate(i, start=sys.maxint+1) + seq, res = 'abc', [(sys.maxint+1,'a'), (sys.maxint+2,'b'), + (sys.maxint+3,'c')] + + def test_main(verbose=None): testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig, TestReversed) diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 230dba2..0bacc83 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -15,18 +15,36 @@ enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { enumobject *en; PyObject *seq = NULL; - static char *kwlist[] = {"sequence", 0}; + PyObject *start = NULL; + static char *kwlist[] = {"sequence", "start", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:enumerate", kwlist, - &seq)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist, + &seq, &start)) return NULL; en = (enumobject *)type->tp_alloc(type, 0); if (en == NULL) return NULL; - en->en_index = 0; + if (start) { + start = PyNumber_Index(start); + if (start == NULL) { + Py_DECREF(en); + return NULL; + } + if (PyLong_Check(start)) { + en->en_index = LONG_MAX; + en->en_longindex = start; + } else { + assert(PyInt_Check(start)); + en->en_index = PyInt_AsLong(start); + en->en_longindex = NULL; + Py_DECREF(start); + } + } else { + en->en_index = 0; + en->en_longindex = NULL; + } en->en_sit = PyObject_GetIter(seq); - en->en_longindex = NULL; if (en->en_sit == NULL) { Py_DECREF(en); return NULL; |