Author: David Lievens <david.liev...@gmail.com>
Branch: py3.3
Changeset: r73946:87225430fd4f
Date: 2014-10-13 15:52 +0100
http://bitbucket.org/pypy/pypy/changeset/87225430fd4f/

Log:    Fix itertools.accumulate to take optional func param

diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -1196,9 +1196,14 @@
 
 
 class W_Accumulate(W_Root):
-    def __init__(self, space, w_iterable):
+    def __init__(self, space, w_iterable, w_func=None):
         self.space = space
         self.w_iterable = w_iterable
+        if w_func is None:  # default operator is add
+            _import = space.getattr(space.builtin, space.wrap("__import__"))
+            _op = space.call_function(_import, space.wrap("operator"))
+            w_func = space.getattr(_op, space.wrap("add")) 
+        self.w_func = w_func
         self.w_total = None
 
     def iter_w(self):
@@ -1210,12 +1215,12 @@
             self.w_total = w_value
             return w_value
 
-        self.w_total = self.space.add(self.w_total, w_value)
+        self.w_total = self.space.call_function(self.w_func, self.w_total, 
w_value)
         return self.w_total
 
-def W_Accumulate__new__(space, w_subtype, w_iterable):
+def W_Accumulate__new__(space, w_subtype, w_iterable, w_func=None):
     r = space.allocate_instance(W_Accumulate, w_subtype)
-    r.__init__(space, space.iter(w_iterable))
+    r.__init__(space, space.iter(w_iterable), w_func)
     return space.wrap(r)
 
 W_Accumulate.typedef = TypeDef("itertools.accumulate",
diff --git a/pypy/module/itertools/test/test_itertools.py 
b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -1,6 +1,11 @@
 import py
+import pytest
 
 
+# def setup_module(mod):
+#     mod.raises = py.test.raises # make raises available from app-level tests
+#     mod.skip = py.test.skip
+
 class AppTestItertools: 
     spaceconfig = dict(usemodules=['itertools'])
 
@@ -969,7 +974,31 @@
             py.test.skip("Requires Python 3.2")
 
     def test_accumulate(self):
+        """copied from ./lib-python/3/test/test_itertools.py"""
         from itertools import accumulate
+        from decimal import Decimal
+        from fractions import Fraction
+        import operator
         expected = [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
+        # one positional arg
         assert list(accumulate(range(10))) == expected
+        # kw arg
         assert list(accumulate(iterable=range(10))) == expected
+        # multiple types
+        for typ in int, complex, Decimal, Fraction:                 
+            assert list(accumulate(map(typ, range(10)))) == list(map(typ, 
expected))
+        assert list(accumulate('abc')) == ['a', 'ab', 'abc']   # works with 
non-numeric
+        assert list(accumulate([])) == []                  # empty iterable
+        assert list(accumulate([7])) == [7]                # iterable of 
length one
+        raises(TypeError, accumulate, range(10), 5, 6)     # too many args
+        raises(TypeError, accumulate)                      # too few args
+        raises(TypeError, accumulate, x=range(10))         # unexpected kwd arg
+        raises(TypeError, list, accumulate([1, "a"]))      # args that don't 
add
+
+        s = [2, 8, 9, 5, 7, 0, 3, 4, 1, 6]
+        assert list(accumulate(s, min)) == [2, 2, 2, 2, 2, 0, 0, 0, 0, 0]
+        assert list(accumulate(s, max)) == [2, 8, 9, 9, 9, 9, 9, 9, 9, 9]
+        assert list(accumulate(s, operator.mul)) == [2, 16, 144, 720, 5040, 0, 
0, 0, 0, 0]
+        raises(TypeError, list, accumulate(s, chr))        # unary-operation
+        raises(TypeError, list, accumulate(s, lambda x,y,z: None))  # ternary
+
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to