Skip to content
Merged
27 changes: 22 additions & 5 deletions Lib/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,6 @@ def reduce(function, sequence, initial=_initial_missing):

return value

try:
from _functools import reduce
except ImportError:
pass


################################################################################
### partial() argument application
Expand Down Expand Up @@ -1122,3 +1117,25 @@ def __get__(self, instance, owner=None):
return val

__class_getitem__ = classmethod(GenericAlias)

def _warn_kwargs(func):
@wraps(func)
def wrapper(*args, **kwargs):
if kwargs:
import os
import warnings
warnings.warn(
'Calling functools.reduce with keyword arguments '
'is deprecated in Python 3.14 and will be '
'forbidden in Python 3.16.',
DeprecationWarning,
skip_file_prefixes=(os.path.dirname(__file__),))
return func(*args, **kwargs)
return wrapper

reduce = _warn_kwargs(reduce)

try:
from _functools import reduce
except ImportError:
pass
6 changes: 6 additions & 0 deletions Lib/test/test_functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,12 @@ class TestReduceC(TestReduce, unittest.TestCase):
class TestReducePy(TestReduce, unittest.TestCase):
reduce = staticmethod(py_functools.reduce)

def test_reduce_with_kwargs(self):
with self.assertWarns(DeprecationWarning):
self.reduce(function=lambda x, y: x + y, sequence=[1, 2, 3, 4, 5], initial=1)
with self.assertWarns(DeprecationWarning):
self.reduce(lambda x, y: x + y, sequence=[1, 2, 3, 4, 5], initial=1)


class TestCmpToKey:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Now calling the Python implementation of the :meth:`functools.reduce` with a
:term:`keyword argument` is raises a :exc:`DeprecationWarning`.
This will be forbidden in Python 3.16 in order to match the C implementation.
Loading