]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-121676: Raise a ``DeprecationWarning`` if the Python implementation of ``functools...
authorKirill Podoprigora <kirill.bast9@mail.ru>
Wed, 1 Jan 2025 11:36:47 +0000 (13:36 +0200)
committerGitHub <noreply@github.com>
Wed, 1 Jan 2025 11:36:47 +0000 (13:36 +0200)
Python implementation of `functools` allows calling `reduce`
with `function` or `sequence` as keyword args. This doesn't
match behavior of our C accelerator and our documentation
for `functools.reduce` states that `function`and `sequence`
are positional-only arguments.

Now calling a Python implementation of `functools.reduce`
with `function` or `sequence` as keyword args would raise
a `DeprecationWarning` and is planned to be prohibited in
Python 3.16.

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Doc/deprecations/pending-removal-in-3.16.rst
Doc/whatsnew/3.14.rst
Lib/functools.py
Lib/test/test_functools.py
Misc/NEWS.d/next/Library/2024-07-13-13-25-31.gh-issue-121676.KDLS11.rst [new file with mode: 0644]

index f2b818f14c63cd94a93562a7e236aa82cb6c5448..d093deb648baf7b881e7628c3133b4a1bd896a14 100644 (file)
@@ -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.
index 63fa21e17bc83446cf2563803502a42497f599e7..4b3f1b2e8eed42f256a24bf3a19318f185764697 100644 (file)
@@ -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
index 786b8aedfd77f5cfcc0e9b667fd2dfe50f3b210a..fd33f0ae479ddc6d12b8fb3332ab464f91d23f98 100644 (file)
@@ -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
index 4a0252cb637a52de77677352ab9d14867a715caa..322248660828248fc6d48a6c4e1d88c220bfa5e4 100644 (file)
@@ -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 (file)
index 0000000..be589b7
--- /dev/null
@@ -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.