Mercurial > cpython-lru_cache-weakref
diff Python/bltinmodule.c @ 17694:aab6c1f19289 legacy-trunk
Generalize zip() to work with iterators.
NEEDS DOC CHANGES.
More AttributeErrors transmuted into TypeErrors, in test_b2.py, and,
again, this strikes me as a good thing.
This checkin completes the iterator generalization work that obviously
needed to be done. Can anyone think of others that should be changed?
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Sun, 06 May 2001 01:05:02 +0000 |
| parents | e9a4e27e8d4e |
| children | f7c385226f65 |
line wrap: on
line diff
--- a/Python/bltinmodule.c Sat May 05 21:36:52 2001 +0000 +++ b/Python/bltinmodule.c Sun May 06 01:05:02 2001 +0000 @@ -2102,7 +2102,8 @@ { PyObject *ret; int itemsize = PySequence_Length(args); - int i, j; + int i; + PyObject *itlist; /* tuple of iterators */ if (itemsize < 1) { PyErr_SetString(PyExc_TypeError, @@ -2112,35 +2113,60 @@ /* args must be a tuple */ assert(PyTuple_Check(args)); + /* allocate result list */ if ((ret = PyList_New(0)) == NULL) return NULL; - for (i = 0;; i++) { - PyObject *next = PyTuple_New(itemsize); - if (!next) { - Py_DECREF(ret); - return NULL; + /* obtain iterators */ + itlist = PyTuple_New(itemsize); + if (itlist == NULL) + goto Fail_ret; + for (i = 0; i < itemsize; ++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, + "zip argument #%d must support iteration", + i+1); + goto Fail_ret_itlist; } - for (j = 0; j < itemsize; j++) { - PyObject *seq = PyTuple_GET_ITEM(args, j); - PyObject *item = PySequence_GetItem(seq, i); + PyTuple_SET_ITEM(itlist, i, it); + } + /* build result into ret list */ + for (;;) { + int status; + PyObject *next = PyTuple_New(itemsize); + if (!next) + goto Fail_ret_itlist; + + for (i = 0; i < itemsize; i++) { + PyObject *it = PyTuple_GET_ITEM(itlist, i); + PyObject *item = PyIter_Next(it); if (!item) { - if (PyErr_ExceptionMatches(PyExc_IndexError)) { - PyErr_Clear(); - Py_DECREF(next); - return ret; + if (PyErr_Occurred()) { + Py_DECREF(ret); + ret = NULL; } Py_DECREF(next); - Py_DECREF(ret); - return NULL; + Py_DECREF(itlist); + return ret; } - PyTuple_SET_ITEM(next, j, item); + PyTuple_SET_ITEM(next, i, item); } - PyList_Append(ret, next); + + status = PyList_Append(ret, next); Py_DECREF(next); + if (status < 0) + goto Fail_ret_itlist; } - /* no return */ + +Fail_ret_itlist: + Py_DECREF(itlist); +Fail_ret: + Py_DECREF(ret); + return NULL; }
