[Python-checkins] r53837 - in python/trunk: Doc/lib/libitertools.tex Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c

Georg Brandl g.brandl at gmx.net
Wed Feb 21 11:33:23 CET 2007


raymond.hettinger schrieb:
> Author: raymond.hettinger
> Date: Wed Feb 21 06:20:38 2007
> New Revision: 53837
> 
> Modified:
>    python/trunk/Doc/lib/libitertools.tex
>    python/trunk/Lib/test/test_itertools.py
>    python/trunk/Misc/NEWS
>    python/trunk/Modules/itertoolsmodule.c
> Log:
> Add itertools.izip_longest().


> +static PyObject *
> +izip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
> +{
> +	iziplongestobject *lz;
> +	Py_ssize_t i;
> +	PyObject *ittuple;  /* tuple of iterators */
> +	PyObject *result;
> +	PyObject *fillvalue = Py_None;
> +	PyObject *filler;
> +	Py_ssize_t tuplesize = PySequence_Length(args);
> +
> +        if (kwds != NULL && PyDict_CheckExact(kwds) && PyDict_Size(kwds) > 0) {
> +                fillvalue = PyDict_GetItemString(kwds, "fillvalue");
> +                if (fillvalue == NULL  ||  PyDict_Size(kwds) > 1) {
> +                        PyErr_SetString(PyExc_TypeError,
> +				"izip_longest() got an unexpected keyword argument");
> +                        return NULL;                      
> +                }
> +        }
> +
> +	/* args must be a tuple */
> +	assert(PyTuple_Check(args));
> +
> +	/* obtain iterators */
> +	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,
> +				    "izip_longest argument #%zd must support iteration",
> +				    i+1);
> +			Py_DECREF(ittuple);
> +			return NULL;
> +		}
> +		PyTuple_SET_ITEM(ittuple, i, it);
> +	}
> +
> +	filler = PyObject_CallFunctionObjArgs((PyObject *)(&repeat_type), fillvalue, NULL);
> +	if (filler == NULL) {
> +		Py_DECREF(ittuple);
> +		return NULL;
> +	}
> +
> +	/* create a result holder */
> +	result = PyTuple_New(tuplesize);
> +	if (result == NULL) {
> +		Py_DECREF(ittuple);
> +		Py_DECREF(filler);
> +		return NULL;
> +	}
> +	for (i=0 ; i < tuplesize ; i++) {
> +		Py_INCREF(Py_None);
> +		PyTuple_SET_ITEM(result, i, Py_None);
> +	}
> +
> +	/* create iziplongestobject structure */
> +	lz = (iziplongestobject *)type->tp_alloc(type, 0);
> +	if (lz == NULL) {
> +		Py_DECREF(ittuple);
> +		Py_DECREF(filler);
> +		Py_DECREF(result);
> +		return NULL;
> +	}
> +	lz->ittuple = ittuple;
> +	lz->tuplesize = tuplesize;
> +	lz->numactive = tuplesize;
> +	lz->result = result;
> +	Py_INCREF(fillvalue);
> +	lz->fillvalue = fillvalue;
> +	Py_INCREF(filler);

filler doesn't need to be INCREF'd here, this causes the refleaks seen in Neal's
automated test run.

Georg



More information about the Python-checkins mailing list