From b5a420883c2ed3a4fc74b212ab0454991fe90bcc Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 8 Aug 2003 05:10:41 +0000 Subject: [PATCH] Modified itertools.izip() to match the behavior of __builtin__.zip() which can now take zero arguments. --- Doc/lib/libitertools.tex | 5 ++++- Lib/test/test_itertools.py | 7 ++++++- Misc/NEWS | 3 +++ Modules/itertoolsmodule.c | 8 ++------ 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Doc/lib/libitertools.tex b/Doc/lib/libitertools.tex index b708050190d..cd7e6de8fa1 100644 --- a/Doc/lib/libitertools.tex +++ b/Doc/lib/libitertools.tex @@ -226,10 +226,13 @@ by functions or loops that truncate the stream. \begin{verbatim} def izip(*iterables): iterables = map(iter, iterables) - while True: + while iterables: result = [i.next() for i in iterables] yield tuple(result) \end{verbatim} + + \versionchanged[When no iterables are specified, returns a zero length + iterator instead of raising a TypeError exception]{2.4} \end{funcdesc} \begin{funcdesc}{repeat}{object\optional{, times}} diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 52ae110ba4d..f96ccd5d48e 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -87,7 +87,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(izip('abcdef', range(3))), zip('abcdef', range(3))) self.assertEqual(take(3,izip('abcdef', count())), zip('abcdef', range(3))) self.assertEqual(list(izip('abcdef')), zip('abcdef')) - self.assertRaises(TypeError, izip) + self.assertEqual(list(izip()), zip()) self.assertRaises(TypeError, izip, 3) self.assertRaises(TypeError, izip, range(3), 3) # Check tuple re-use (implementation detail) @@ -199,6 +199,8 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(ValueError, dropwhile(errfunc, [(4,5)]).next) def test_StopIteration(self): + self.assertRaises(StopIteration, izip().next) + for f in (chain, cycle, izip): self.assertRaises(StopIteration, f([]).next) self.assertRaises(StopIteration, f(StopNow()).next) @@ -540,6 +542,9 @@ True >>> no(lambda x: x%2==0, [1, 2, 5, 9]) False +>>> quantify(lambda x: x%2==0, xrange(99)) +50 + >>> list(window('abc')) [('a', 'b'), ('b', 'c')] diff --git a/Misc/NEWS b/Misc/NEWS index 34786bfaca2..410391cd135 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -23,6 +23,9 @@ Extension modules Library ------- +- itertools.izip() with no arguments now returns an empty iterator instead + of raising a TypeError exception. + - _strptime.py now has a behind-the-scenes caching mechanism for the most recent TimeRE instance used along with the last five unique directive patterns. The overall module was also made more thread-safe. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index e63d02a4c94..4a99fcebec6 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1510,12 +1510,6 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *result; int tuplesize = PySequence_Length(args); - if (tuplesize < 1) { - PyErr_SetString(PyExc_TypeError, - "izip() requires at least one sequence"); - return NULL; - } - /* args must be a tuple */ assert(PyTuple_Check(args)); @@ -1598,6 +1592,8 @@ izip_next(izipobject *lz) PyObject *it; PyObject *item; + if (tuplesize == 0) + return NULL; if (result->ob_refcnt == 1) { for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i);