Skip to content

gh-161004: Align Python implementation of functools.reduce with C implementation - #161025

Closed
NotorandXor256 wants to merge 1 commit into
python:mainfrom
NotorandXor256:fix/functools_reduce
Closed

NotorandXor256 wants to merge 1 commit into
python:mainfrom
NotorandXor256:fix/functools_reduce

Conversation

@NotorandXor256

@NotorandXor256 NotorandXor256 commented Oct 31, 2026 •

Copy link
Copy Markdown

Fixes #161004
This PR fix functools.reduce.The C functools_reduce calls PyObject_GetIter(seq) once and then only PyIter_Next(it). The Python version calls iter(sequence) and then for element in it:, which calls iter() again on the iterator.

this PR fix this behavior by change for loop for element in it: to while loop. While loop is terminated next(element) throw a StopIteration exception and error handle it and break the loop

this PR also add a test and change the documentation

@bedevere-app

bedevere-app Bot commented Oct 31, 2026

Copy link
Copy Markdown

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@NotorandXor256 NotorandXor256 changed the title Fixed py_functools.reduce and added test_reduce.py as test (issue #161004) gh-161004: Fixed py_functools.reduce and added test_reduce.py as test (issue #161004) Oct 31, 2026
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #35548826 | 📁 Comparing deb5f70 against main (683fca8)

  🔍 Preview build  

1 file changed
± library/functools.html

@picnixz picnixz changed the title gh-161004: Fixed py_functools.reduce and added test_reduce.py as test (issue #161004) gh-161004: Align Python implementation of functools.reduce with C implementation Oct 31, 2026
Comment thread Doc/library/functools.rst
else:
value = initial
for element in it:
while(True):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while(True):
while True:

I don't really think it's necessary to change this though as it's a "roughly equivalent" code.

Comment thread Lib/functools.py
Comment on lines +263 to +267
try:
element = next(it)
except StopIteration:
# Stop when no elements are left
break

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try:
element = next(it)
except StopIteration:
# Stop when no elements are left
break
try:
element = next(it)
except StopIteration:
break

Comment thread Lib/functools.py
value = initial

for element in it:
while(True):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while(True):
# Mirror the C implementation which calls sequence.__iter__() only once.
while True:

Comment thread Lib/test/test_reduce.py
@@ -0,0 +1,28 @@
import unittest

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this test in test_functools.py instead.

Comment thread Lib/functools.py
# Stop when no elements are left
break
value = function(value, element)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep that new line.

@rhettinger

Copy link
Copy Markdown
Contributor

I wouldn't make this edit. As noted in the issue, the iterator protocol specifically allows this. Also, this code is a "rough equivalent" intended to communicate the concept of what reduce does.

@rhettinger rhettinger added the pending The issue will be closed if no feedback is provided label Oct 31, 2026
@rhettinger rhettinger closed this Oct 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review pending The issue will be closed if no feedback is provided

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pure-Python functools.reduce calls iter() twice, unlike the C implementation

3 participants