]> granicus.if.org Git - python/commitdiff
Add alternate constructor for itertools.chain().
authorRaymond Hettinger <python@rcn.com>
Thu, 28 Feb 2008 22:46:41 +0000 (22:46 +0000)
committerRaymond Hettinger <python@rcn.com>
Thu, 28 Feb 2008 22:46:41 +0000 (22:46 +0000)
Lib/test/test_itertools.py
Misc/NEWS
Modules/itertoolsmodule.c

index 41e93627f5170b0e4e80b0e8648f96c7aefb5ce0..500afef01e5b31d6466c1cf1f20e05f47d7c638f 100644 (file)
@@ -52,6 +52,13 @@ class TestBasicOps(unittest.TestCase):
         self.assertEqual(take(4, chain('abc', 'def')), list('abcd'))
         self.assertRaises(TypeError, list,chain(2, 3))
 
+    def test_chain_from_iterable(self):
+        self.assertEqual(list(chain.from_iterable(['abc', 'def'])), list('abcdef'))
+        self.assertEqual(list(chain.from_iterable(['abc'])), list('abc'))
+        self.assertEqual(list(chain.from_iterable([''])), [])
+        self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd'))
+        self.assertRaises(TypeError, list, chain.from_iterable([2, 3]))
+
     def test_combinations(self):
         self.assertRaises(TypeError, combinations, 'abc')   # missing r argument
         self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments
index c28fd856770ef80279cfe8585f582909de489dc1..6df4ebce5f973adee05db24dc7037379dea0b8c4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1247,6 +1247,8 @@ Extension Modules
 - itertools.starmap() now accepts any iterable input. Previously, it required
   the function inputs to be tuples.
 
+- itertools.chain() now has an alterate constructor, chain.from_iterable().
+
 - Issue #1646: Make socket support TIPC. The socket module now has support
   for TIPC under Linux, see http://tipc.sf.net/ for more information.
 
index 3b8339cc56fc01bdb86d37825514c4fe91b3d23f..f29077a3af1a2704b767cb0e5033da77d19ff1e4 100644 (file)
@@ -1638,6 +1638,18 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        return chain_new_internal(type, source);
 }
 
+static PyObject *
+chain_new_from_iterable(PyTypeObject *type, PyObject *arg)
+{
+       PyObject *source;
+       
+       source = PyObject_GetIter(arg);
+       if (source == NULL)
+               return NULL;
+
+       return chain_new_internal(type, source);
+}
+
 static void
 chain_dealloc(chainobject *lz)
 {
@@ -1696,6 +1708,18 @@ Return a chain object whose .next() method returns elements from the\n\
 first iterable until it is exhausted, then elements from the next\n\
 iterable, until all of the iterables are exhausted.");
 
+PyDoc_STRVAR(chain_from_iterable_doc,
+"chain.from_iterable(iterable) --> chain object\n\
+\n\
+Alternate chain() contructor taking a single iterable argument\n\
+that evaluates lazily.");
+
+static PyMethodDef chain_methods[] = {
+       {"from_iterable", (PyCFunction) chain_new_from_iterable,        METH_O | METH_CLASS,
+               chain_from_iterable_doc},
+       {NULL,          NULL}   /* sentinel */
+};
+
 static PyTypeObject chain_type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "itertools.chain",              /* tp_name */
@@ -1726,7 +1750,7 @@ static PyTypeObject chain_type = {
        0,                              /* tp_weaklistoffset */
        PyObject_SelfIter,              /* tp_iter */
        (iternextfunc)chain_next,       /* tp_iternext */
-       0,                              /* tp_methods */
+       chain_methods,                  /* tp_methods */
        0,                              /* tp_members */
        0,                              /* tp_getset */
        0,                              /* tp_base */