summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-07-03 06:02:15 (GMT)
committerGitHub <noreply@github.com>2024-07-03 06:02:15 (GMT)
commitff5806c78edda1feed61254ac55193772dc9ec48 (patch)
treeb7559dfb94f0ec9ade90ba96a2e6a853f6f4cd1e /Lib
parentf09d184821efd9438d092643881e28bdf8de4de5 (diff)
downloadcpython-ff5806c78edda1feed61254ac55193772dc9ec48.zip
cpython-ff5806c78edda1feed61254ac55193772dc9ec48.tar.gz
cpython-ff5806c78edda1feed61254ac55193772dc9ec48.tar.bz2
gh-121027: Make the functools.partial object a method descriptor (GH-121089)
Co-authored-by: d.grigonis <dgrigonis@users.noreply.github.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/functools.py10
-rw-r--r--Lib/test/test_functools.py4
-rw-r--r--Lib/test/test_inspect/test_inspect.py38
3 files changed, 20 insertions, 32 deletions
diff --git a/Lib/functools.py b/Lib/functools.py
index d04957c..a10493f 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -18,6 +18,7 @@ from abc import get_cache_token
from collections import namedtuple
# import types, weakref # Deferred to single_dispatch()
from reprlib import recursive_repr
+from types import MethodType
from _thread import RLock
# Avoid importing types, so we can speedup import time
@@ -314,12 +315,7 @@ class partial:
def __get__(self, obj, objtype=None):
if obj is None:
return self
- import warnings
- warnings.warn('functools.partial will be a method descriptor in '
- 'future Python versions; wrap it in staticmethod() '
- 'if you want to preserve the old behavior',
- FutureWarning, 2)
- return self
+ return MethodType(self, obj)
def __reduce__(self):
return type(self), (self.func,), (self.func, self.args,
@@ -402,7 +398,7 @@ class partialmethod(object):
def __get__(self, obj, cls=None):
get = getattr(self.func, "__get__", None)
result = None
- if get is not None and not isinstance(self.func, partial):
+ if get is not None:
new_func = get(obj, cls)
if new_func is not self.func:
# Assume __get__ returning something new indicates the
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index 1ce0f4d..492a16a 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -405,9 +405,7 @@ class TestPartial:
self.assertEqual(A.meth(3, b=4), ((1, 3), {'a': 2, 'b': 4}))
self.assertEqual(A.cmeth(3, b=4), ((1, A, 3), {'a': 2, 'b': 4}))
self.assertEqual(A.smeth(3, b=4), ((1, 3), {'a': 2, 'b': 4}))
- with self.assertWarns(FutureWarning) as w:
- self.assertEqual(a.meth(3, b=4), ((1, 3), {'a': 2, 'b': 4}))
- self.assertEqual(w.filename, __file__)
+ self.assertEqual(a.meth(3, b=4), ((1, a, 3), {'a': 2, 'b': 4}))
self.assertEqual(a.cmeth(3, b=4), ((1, A, 3), {'a': 2, 'b': 4}))
self.assertEqual(a.smeth(3, b=4), ((1, 3), {'a': 2, 'b': 4}))
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
index 308c098..d39c3cc 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -3868,17 +3868,15 @@ class TestSignatureObject(unittest.TestCase):
with self.subTest('partial'):
class CM(type):
- __call__ = functools.partial(lambda x, a: (x, a), 2)
+ __call__ = functools.partial(lambda x, a, b: (x, a, b), 2)
class C(metaclass=CM):
- def __init__(self, b):
+ def __init__(self, c):
pass
- with self.assertWarns(FutureWarning):
- self.assertEqual(C(1), (2, 1))
- with self.assertWarns(FutureWarning):
- self.assertEqual(self.signature(C),
- ((('a', ..., ..., "positional_or_keyword"),),
- ...))
+ self.assertEqual(C(1), (2, C, 1))
+ self.assertEqual(self.signature(C),
+ ((('b', ..., ..., "positional_or_keyword"),),
+ ...))
with self.subTest('partialmethod'):
class CM(type):
@@ -4024,14 +4022,12 @@ class TestSignatureObject(unittest.TestCase):
with self.subTest('partial'):
class C:
- __init__ = functools.partial(lambda x, a: None, 2)
+ __init__ = functools.partial(lambda x, a, b: None, 2)
- with self.assertWarns(FutureWarning):
- C(1) # does not raise
- with self.assertWarns(FutureWarning):
- self.assertEqual(self.signature(C),
- ((('a', ..., ..., "positional_or_keyword"),),
- ...))
+ C(1) # does not raise
+ self.assertEqual(self.signature(C),
+ ((('b', ..., ..., "positional_or_keyword"),),
+ ...))
with self.subTest('partialmethod'):
class C:
@@ -4284,15 +4280,13 @@ class TestSignatureObject(unittest.TestCase):
with self.subTest('partial'):
class C:
- __call__ = functools.partial(lambda x, a: (x, a), 2)
+ __call__ = functools.partial(lambda x, a, b: (x, a, b), 2)
c = C()
- with self.assertWarns(FutureWarning):
- self.assertEqual(c(1), (2, 1))
- with self.assertWarns(FutureWarning):
- self.assertEqual(self.signature(c),
- ((('a', ..., ..., "positional_or_keyword"),),
- ...))
+ self.assertEqual(c(1), (2, c, 1))
+ self.assertEqual(self.signature(C()),
+ ((('b', ..., ..., "positional_or_keyword"),),
+ ...))
with self.subTest('partialmethod'):
class C: