diff options
author | Kirill Podoprigora <kirill.bast9@mail.ru> | 2025-01-01 11:36:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-01 11:36:47 (GMT) |
commit | d903b17499b1a3bfb3ea848f6a1b6da02eac3328 (patch) | |
tree | 070a24e1cd2e3ebdb2ce6a739185f265138b244c /Lib | |
parent | c5438fdf4706a70bdd19338edc000dacffff6837 (diff) | |
download | cpython-d903b17499b1a3bfb3ea848f6a1b6da02eac3328.zip cpython-d903b17499b1a3bfb3ea848f6a1b6da02eac3328.tar.gz cpython-d903b17499b1a3bfb3ea848f6a1b6da02eac3328.tar.bz2 |
gh-121676: Raise a ``DeprecationWarning`` if the Python implementation of ``functools.reduce`` is called with `function` or `sequence` as a keyword args (#121677)
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>
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/functools.py | 33 | ||||
-rw-r--r-- | Lib/test/test_functools.py | 6 |
2 files changed, 34 insertions, 5 deletions
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: |