summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/deprecations/pending-removal-in-3.16.rst5
-rw-r--r--Doc/whatsnew/3.14.rst5
-rw-r--r--Lib/functools.py33
-rw-r--r--Lib/test/test_functools.py6
-rw-r--r--Misc/NEWS.d/next/Library/2024-07-13-13-25-31.gh-issue-121676.KDLS11.rst3
5 files changed, 47 insertions, 5 deletions
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst
index f2b818f..d093deb 100644
--- a/Doc/deprecations/pending-removal-in-3.16.rst
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -79,3 +79,8 @@ Pending removal in Python 3.16
* The undocumented and unused :attr:`!TarFile.tarfile` attribute
has been deprecated since Python 3.13.
+
+* :mod:`functools`:
+
+ * Calling the Python implementation of :func:`functools.reduce` with *function*
+ or *sequence* as keyword arguments has been deprecated since Python 3.14.
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 63fa21e..4b3f1b2 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -744,6 +744,11 @@ Deprecated
as a single positional argument.
(Contributed by Serhiy Storchaka in :gh:`109218`.)
+* :mod:`functools`:
+ Calling the Python implementation of :func:`functools.reduce` with *function*
+ or *sequence* as keyword arguments is now deprecated.
+ (Contributed by Kirill Podoprigora in :gh:`121676`.)
+
* :mod:`os`:
:term:`Soft deprecate <soft deprecated>` :func:`os.popen` and
:func:`os.spawn* <os.spawnl>` functions. They should no longer be used to
diff --git a/Lib/functools.py b/Lib/functools.py
index 786b8ae..fd33f0a 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -264,11 +264,6 @@ def reduce(function, sequence, initial=_initial_missing):
return value
-try:
- from _functools import reduce
-except ImportError:
- pass
-
################################################################################
### partial() argument application
@@ -1124,3 +1119,31 @@ class cached_property:
return val
__class_getitem__ = classmethod(GenericAlias)
+
+def _warn_python_reduce_kwargs(py_reduce):
+ @wraps(py_reduce)
+ def wrapper(*args, **kwargs):
+ if 'function' in kwargs or 'sequence' in kwargs:
+ import os
+ import warnings
+ warnings.warn(
+ 'Calling functools.reduce with keyword arguments '
+ '"function" or "sequence" '
+ 'is deprecated in Python 3.14 and will be '
+ 'forbidden in Python 3.16.',
+ DeprecationWarning,
+ skip_file_prefixes=(os.path.dirname(__file__),))
+ return py_reduce(*args, **kwargs)
+ return wrapper
+
+reduce = _warn_python_reduce_kwargs(reduce)
+del _warn_python_reduce_kwargs
+
+# The import of the C accelerated version of reduce() has been moved
+# here due to gh-121676. In Python 3.16, _warn_python_reduce_kwargs()
+# should be removed and the import block should be moved back right
+# after the definition of reduce().
+try:
+ from _functools import reduce
+except ImportError:
+ pass
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 4a0252c..3222486 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1045,6 +1045,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:
diff --git a/Misc/NEWS.d/next/Library/2024-07-13-13-25-31.gh-issue-121676.KDLS11.rst b/Misc/NEWS.d/next/Library/2024-07-13-13-25-31.gh-issue-121676.KDLS11.rst
new file mode 100644
index 0000000..be589b7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-07-13-13-25-31.gh-issue-121676.KDLS11.rst
@@ -0,0 +1,3 @@
+Deprecate calling the Python implementation of :meth:`functools.reduce`
+with a ``function`` or ``sequence`` as a :term:`keyword argument`.
+This will be forbidden in Python 3.16 in order to match the C implementation.