From deb5f70855d79f1e9b8a7c3b1f5f4944cd17f8f9 Mon Sep 17 00:00:00 2001 From: Notorandxor_turing <105069473+NotorandXor256@users.noreply.github.com> Date: Sun, 1 Nov 2026 00:14:25 +0530 Subject: [PATCH] Fixed py_functools.reduce and added test_reduce.py as test (issue python#161004) --- Doc/library/functools.rst | 6 +++++- Lib/functools.py | 8 ++++++-- Lib/test/test_reduce.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 Lib/test/test_reduce.py diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 4eeafad3fbd9156..5ad409872cb9925 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -476,7 +476,11 @@ The :mod:`!functools` module defines the following functions: value = next(it) else: value = initial - for element in it: + while(True): + try: + element = next(it) + except StopIteration: + break value = function(value, element) return value diff --git a/Lib/functools.py b/Lib/functools.py index 2c08791d4d2651b..f21fd26381cf884 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -259,9 +259,13 @@ def reduce(function, sequence, /, initial=_initial_missing): else: value = initial - for element in it: + while(True): + try: + element = next(it) + except StopIteration: + # Stop when no elements are left + break value = function(value, element) - return value try: diff --git a/Lib/test/test_reduce.py b/Lib/test/test_reduce.py new file mode 100644 index 000000000000000..5cddee2fb293a2c --- /dev/null +++ b/Lib/test/test_reduce.py @@ -0,0 +1,28 @@ +import unittest +import operator +import sys +import functools as c_functools + +class Test_reduce(unittest.TestCase): + def test_add_func(self): + del sys.modules['functools'] + sys.modules['_functools'] = None # block the C accelerator + import functools as py_functools + + class Iterator: + def __init__(self): + self.items = [1, 2, 3, 4, 4] + def __next__(self): + if not self.items: + raise StopIteration + return self.items.pop(0) + class Iterable: + def __iter__(self): + return Iterator() + self.assertEqual( + c_functools.reduce(operator.add, Iterable()), + py_functools.reduce(operator.add, Iterable()) + ) + +if __name__ == "__main__": + unittest.main()