Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,11 @@ The :mod:`!functools` module defines the following functions:
value = next(it)
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.

try:
element = next(it)
except StopIteration:
break
value = function(value, element)
return value

Expand Down
8 changes: 6 additions & 2 deletions Lib/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,13 @@ def reduce(function, sequence, /, initial=_initial_missing):
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):
# Mirror the C implementation which calls sequence.__iter__() only once.
while True:

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

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

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.

return value

try:
Expand Down
28 changes: 28 additions & 0 deletions Lib/test/test_reduce.py
Original file line number Diff line number Diff line change
@@ -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.

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()
Loading