[Python-checkins] r76025 - in python/trunk: Lib/test/test_itertools.py Misc/NEWS Modules/itertoolsmodule.c
raymond.hettinger
python-checkins at python.org
Sun Nov 1 21:45:17 CET 2009
Author: raymond.hettinger
Date: Sun Nov 1 21:45:16 2009
New Revision: 76025
Log:
Fix exception handling in itertools.izip_longest().
Modified:
python/trunk/Lib/test/test_itertools.py
python/trunk/Misc/NEWS
python/trunk/Modules/itertoolsmodule.c
Modified: python/trunk/Lib/test/test_itertools.py
==============================================================================
--- python/trunk/Lib/test/test_itertools.py (original)
+++ python/trunk/Lib/test/test_itertools.py Sun Nov 1 21:45:16 2009
@@ -571,6 +571,46 @@
ids = map(id, list(izip_longest('abc', 'def')))
self.assertEqual(len(dict.fromkeys(ids)), len(ids))
+ def test_bug_7244(self):
+
+ class Repeater(object):
+ # this class is similar to itertools.repeat
+ def __init__(self, o, t, e):
+ self.o = o
+ self.t = int(t)
+ self.e = e
+ def __iter__(self): # its iterator is itself
+ return self
+ def next(self):
+ if self.t > 0:
+ self.t -= 1
+ return self.o
+ else:
+ raise self.e
+
+ # Formerly this code in would fail in debug mode
+ # with Undetected Error and Stop Iteration
+ r1 = Repeater(1, 3, StopIteration)
+ r2 = Repeater(2, 4, StopIteration)
+ def run(r1, r2):
+ result = []
+ for i, j in izip_longest(r1, r2, fillvalue=0):
+ with test_support.captured_output('stdout'):
+ print (i, j)
+ result.append((i, j))
+ return result
+ self.assertEqual(run(r1, r2), [(1,2), (1,2), (1,2), (0,2)])
+
+ # Formerly, the RuntimeError would be lost
+ # and StopIteration would stop as expected
+ r1 = Repeater(1, 3, RuntimeError)
+ r2 = Repeater(2, 4, StopIteration)
+ it = izip_longest(r1, r2, fillvalue=0)
+ self.assertEqual(next(it), (1, 2))
+ self.assertEqual(next(it), (1, 2))
+ self.assertEqual(next(it), (1, 2))
+ self.assertRaises(RuntimeError, next, it)
+
def test_product(self):
for args, result in [
([], [()]), # zero iterables
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Sun Nov 1 21:45:16 2009
@@ -15,6 +15,9 @@
- Remove length limitation when constructing a complex number from a
unicode string.
+- Issue #7244: itertools.izip_longest() no longer ignores exceptions
+ raised during the formation of an output tuple.
+
- Issue #1087418: Boost performance of bitwise operations for longs.
- Issue #1722344: threading._shutdown() is now called in Py_Finalize(), which
Modified: python/trunk/Modules/itertoolsmodule.c
==============================================================================
--- python/trunk/Modules/itertoolsmodule.c (original)
+++ python/trunk/Modules/itertoolsmodule.c Sun Nov 1 21:45:16 2009
@@ -3865,71 +3865,73 @@
static PyObject *
izip_longest_next(iziplongestobject *lz)
{
- Py_ssize_t i;
- Py_ssize_t tuplesize = lz->tuplesize;
- PyObject *result = lz->result;
- PyObject *it;
- PyObject *item;
- PyObject *olditem;
+ Py_ssize_t i;
+ Py_ssize_t tuplesize = lz->tuplesize;
+ PyObject *result = lz->result;
+ PyObject *it;
+ PyObject *item;
+ PyObject *olditem;
- if (tuplesize == 0)
- return NULL;
+ if (tuplesize == 0)
+ return NULL;
if (lz->numactive == 0)
return NULL;
- if (Py_REFCNT(result) == 1) {
- Py_INCREF(result);
- for (i=0 ; i < tuplesize ; i++) {
- it = PyTuple_GET_ITEM(lz->ittuple, i);
+ if (Py_REFCNT(result) == 1) {
+ Py_INCREF(result);
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
if (it == NULL) {
Py_INCREF(lz->fillvalue);
item = lz->fillvalue;
} else {
- item = (*Py_TYPE(it)->tp_iternext)(it);
+ item = PyIter_Next(it);
if (item == NULL) {
- lz->numactive -= 1;
- if (lz->numactive == 0) {
+ lz->numactive -= 1;
+ if (lz->numactive == 0 || PyErr_Occurred()) {
+ lz->numactive = 0;
Py_DECREF(result);
return NULL;
} else {
Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = lz->fillvalue;
PyTuple_SET_ITEM(lz->ittuple, i, NULL);
Py_DECREF(it);
}
}
}
- olditem = PyTuple_GET_ITEM(result, i);
- PyTuple_SET_ITEM(result, i, item);
- Py_DECREF(olditem);
- }
- } else {
- result = PyTuple_New(tuplesize);
- if (result == NULL)
- return NULL;
- for (i=0 ; i < tuplesize ; i++) {
- it = PyTuple_GET_ITEM(lz->ittuple, i);
+ olditem = PyTuple_GET_ITEM(result, i);
+ PyTuple_SET_ITEM(result, i, item);
+ Py_DECREF(olditem);
+ }
+ } else {
+ result = PyTuple_New(tuplesize);
+ if (result == NULL)
+ return NULL;
+ for (i=0 ; i < tuplesize ; i++) {
+ it = PyTuple_GET_ITEM(lz->ittuple, i);
if (it == NULL) {
Py_INCREF(lz->fillvalue);
item = lz->fillvalue;
} else {
- item = (*Py_TYPE(it)->tp_iternext)(it);
+ item = PyIter_Next(it);
if (item == NULL) {
- lz->numactive -= 1;
- if (lz->numactive == 0) {
+ lz->numactive -= 1;
+ if (lz->numactive == 0 || PyErr_Occurred()) {
+ lz->numactive = 0;
Py_DECREF(result);
return NULL;
} else {
Py_INCREF(lz->fillvalue);
- item = lz->fillvalue;
+ item = lz->fillvalue;
PyTuple_SET_ITEM(lz->ittuple, i, NULL);
Py_DECREF(it);
}
}
}
- PyTuple_SET_ITEM(result, i, item);
- }
- }
- return result;
+ PyTuple_SET_ITEM(result, i, item);
+ }
+ }
+ return result;
}
PyDoc_STRVAR(izip_longest_doc,
More information about the Python-checkins
mailing list