[Python-checkins] cpython (merge 3.5 -> default): Issue #25718: Fixed pickling and copying the accumulate() iterator with total

serhiy.storchaka python-checkins at python.org
Sun Mar 6 07:02:51 EST 2016


https://hg.python.org/cpython/rev/49c035b30e18
changeset:   100423:49c035b30e18
parent:      100421:37cdbe0a16a4
parent:      100422:f3c54cbac3de
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Mar 06 14:02:26 2016 +0200
summary:
  Issue #25718: Fixed pickling and copying the accumulate() iterator with total is None.

files:
  Lib/test/test_itertools.py |  10 ++++++++++
  Misc/NEWS                  |   3 +++
  Modules/itertoolsmodule.c  |  17 +++++++++++++++++
  3 files changed, 30 insertions(+), 0 deletions(-)


diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -1448,6 +1448,16 @@
         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')
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -201,6 +201,9 @@
 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.
 
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -3464,6 +3464,23 @@
 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);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list