Skip to content

Commit f130d35

Browse files
Fixed py_functools.reduce and added test_reduce.py as test (issue #161004
1 parent 28bec98 commit f130d35

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

‎Doc/library/functools.rst‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,8 +476,12 @@ The :mod:`!functools` module defines the following functions:
476476
value = next(it)
477477
else:
478478
value = initial
479-
for element in it:
480-
value = function(value, element)
479+
while(True):
480+
try:
481+
element = next(it)
482+
except StopIteration:
483+
break
484+
value = function(value, element)
481485
return value
482486

483487
See :func:`itertools.accumulate` for an iterator that yields all intermediate

‎Lib/functools.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,12 @@ def reduce(function, sequence, /, initial=_initial_missing):
259259
else:
260260
value = initial
261261

262-
for element in it:
262+
while(True):
263+
try:
264+
element = next(it)
265+
except StopIteration:
266+
# Stop when no elements are left
267+
break
263268
value = function(value, element)
264269

265270
return value

‎Lib/test/test_reduce.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import unittest
2+
import operator
3+
import sys
4+
import functools as c_functools
5+
6+
class Test_reduce(unittest.TestCase):
7+
def test_add_func(self):
8+
del sys.modules['functools']
9+
sys.modules['_functools'] = None # block the C accelerator
10+
import functools as py_functools
11+
12+
class Iterator:
13+
def __init__(self):
14+
self.items = [1, 2, 3, 4, 4]
15+
def __next__(self):
16+
if not self.items:
17+
raise StopIteration
18+
return self.items.pop(0)
19+
class Iterable:
20+
def __iter__(self):
21+
return Iterator()
22+
self.assertEqual(
23+
c_functools.reduce(operator.add, Iterable()),
24+
py_functools.reduce(operator.add, Iterable())
25+
)
26+
27+
if __name__ == "__main__":
28+
unittest.main()

0 commit comments

Comments
 (0)