Commit d5516251 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #25718: Fixed pickling and copying the accumulate() iterator with total is None.

parent a01a144a
......@@ -1398,6 +1398,16 @@ class TestExamples(unittest.TestCase):
self.assertEqual(list(copy.deepcopy(it)), accumulated[1:])
self.assertEqual(list(copy.copy(it)), accumulated[1:])
def test_accumulate_reducible_none(self):
# Issue #25718: total is None
it = accumulate([None, None, None], operator.is_)
self.assertEqual(next(it), None)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
it_copy = pickle.loads(pickle.dumps(it, proto))
self.assertEqual(list(it_copy), [True, False])
self.assertEqual(list(copy.deepcopy(it)), [True, False])
self.assertEqual(list(copy.copy(it)), [True, False])
def test_chain(self):
self.assertEqual(''.join(chain('ABC', 'DEF')), 'ABCDEF')
......
......@@ -91,6 +91,9 @@ Core and Builtins
Library
-------
- Issue #25718: Fixed pickling and copying the accumulate() iterator with
total is None.
- Issue #26475: Fixed debugging output for regular expressions with the (?x)
flag.
......
......@@ -3460,6 +3460,23 @@ accumulate_next(accumulateobject *lz)
static PyObject *
accumulate_reduce(accumulateobject *lz)
{
if (lz->total == Py_None) {
PyObject *it;
if (PyType_Ready(&chain_type) < 0)
return NULL;
if (PyType_Ready(&islice_type) < 0)
return NULL;
it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O",
lz->total, lz->it);
if (it == NULL)
return NULL;
it = PyObject_CallFunction((PyObject *)Py_TYPE(lz), "NO",
it, lz->binop ? lz->binop : Py_None);
if (it == NULL)
return NULL;
return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None);
}
return Py_BuildValue("O(OO)O", Py_TYPE(lz),
lz->it, lz->binop?lz->binop:Py_None,
lz->total?lz->total:Py_None);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment