Hi again, i wrote a small patch that changes itertools.chain to take a "link" keyword argument. If given, it is iterated between the normal arguments, otherwise the behavior is unchanged.
I'd like to hear your opinion on both, the functionality and the actual implementation (as this is one of the first things i ever wrote in C). till then, David.
Index: python/dist/src/Modules/itertoolsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v retrieving revision 1.41 diff -c -r1.41 itertoolsmodule.c *** python/dist/src/Modules/itertoolsmodule.c 26 Aug 2005 06:42:30 -0000 1.41 --- python/dist/src/Modules/itertoolsmodule.c 30 Sep 2005 22:28:38 -0000 *************** *** 1561,1587 **** int tuplesize = PySequence_Length(args); int i; PyObject *ittuple; ! if (!_PyArg_NoKeywords("chain()", kwds)) ! return NULL; /* obtain iterators */ assert(PyTuple_Check(args)); ittuple = PyTuple_New(tuplesize); if(ittuple == NULL) return NULL; ! for (i=0; i < tuplesize; ++i) { ! PyObject *item = PyTuple_GET_ITEM(args, i); ! PyObject *it = PyObject_GetIter(item); ! if (it == NULL) { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_Format(PyExc_TypeError, ! "chain argument #%d must support iteration", ! i+1); ! Py_DECREF(ittuple); ! return NULL; } - PyTuple_SET_ITEM(ittuple, i, it); } /* create chainobject structure */ --- 1561,1621 ---- int tuplesize = PySequence_Length(args); int i; PyObject *ittuple; + PyObject *link = NULL; ! if (kwds != NULL && PyDict_Check(kwds)) { ! link = PyDict_GetItemString(kwds, "link"); ! if (link != NULL) ! /* create more space for the link iterators */ ! tuplesize = tuplesize*2-1; ! } /* obtain iterators */ assert(PyTuple_Check(args)); ittuple = PyTuple_New(tuplesize); if(ittuple == NULL) return NULL; ! if (link == NULL) { ! /* no keyword argument provided */ ! for (i=0; i < tuplesize; ++i) { ! PyObject *item = PyTuple_GET_ITEM(args, i); ! PyObject *it = PyObject_GetIter(item); ! if (it == NULL) { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_Format(PyExc_TypeError, ! "chain argument #%d must support iteration", ! i+1); ! Py_DECREF(ittuple); ! return NULL; ! } ! PyTuple_SET_ITEM(ittuple, i, it); ! } ! } ! else { ! for (i=0; i < tuplesize; ++i) { ! PyObject *it = NULL; ! if (i%2 == 0) { ! PyObject *item = PyTuple_GET_ITEM(args, i/2); ! it = PyObject_GetIter(item); ! } ! else { ! it = PyObject_GetIter(link); ! } ! if (it == NULL) { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) { ! if (i%2 == 0) ! PyErr_Format(PyExc_TypeError, ! "chain argument #%d must support iteration", ! i/2+1); ! else ! PyErr_Format(PyExc_TypeError, ! "chain keyword argument link must support iteration"); ! } ! Py_DECREF(ittuple); ! return NULL; ! } ! PyTuple_SET_ITEM(ittuple, i, it); } } /* create chainobject structure */
-- http://mail.python.org/mailman/listinfo/python-list