summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2021-04-09 15:51:22 (GMT)
committerGitHub <noreply@github.com>2021-04-09 15:51:22 (GMT)
commit507a574de31a1bd7fed8ba4f04afa285d985109b (patch)
tree44fb249533ae98698ef7736bc050df450f9a07e1 /Lib/test
parent150af7543214e1541fa582374502ac1cd70e8eb4 (diff)
downloadcpython-507a574de31a1bd7fed8ba4f04afa285d985109b.zip
cpython-507a574de31a1bd7fed8ba4f04afa285d985109b.tar.gz
cpython-507a574de31a1bd7fed8ba4f04afa285d985109b.tar.bz2
bpo-43682: @staticmethod inherits attributes (GH-25268)
Static methods (@staticmethod) and class methods (@classmethod) now inherit the method attributes (__module__, __name__, __qualname__, __doc__, __annotations__) and have a new __wrapped__ attribute. Changes: * Add a repr() method to staticmethod and classmethod types. * Add tests on the @classmethod decorator.
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_decorators.py26
-rw-r--r--Lib/test/test_descr.py18
-rw-r--r--Lib/test/test_pydoc.py6
-rw-r--r--Lib/test/test_reprlib.py4
4 files changed, 41 insertions, 13 deletions
diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py
index 298979e..7d0243a 100644
--- a/Lib/test/test_decorators.py
+++ b/Lib/test/test_decorators.py
@@ -1,3 +1,4 @@
+from test import support
import unittest
def funcattrs(**kwds):
@@ -76,11 +77,28 @@ class TestDecorators(unittest.TestCase):
self.assertEqual(C.foo(), 42)
self.assertEqual(C().foo(), 42)
- def test_staticmethod_function(self):
- @staticmethod
- def notamethod(x):
+ def check_wrapper_attrs(self, method_wrapper, format_str):
+ def func(x):
return x
- self.assertRaises(TypeError, notamethod, 1)
+ wrapper = method_wrapper(func)
+
+ self.assertIs(wrapper.__func__, func)
+ self.assertIs(wrapper.__wrapped__, func)
+
+ for attr in ('__module__', '__qualname__', '__name__',
+ '__doc__', '__annotations__'):
+ self.assertIs(getattr(wrapper, attr),
+ getattr(func, attr))
+
+ self.assertEqual(repr(wrapper), format_str.format(func))
+
+ self.assertRaises(TypeError, wrapper, 1)
+
+ def test_staticmethod(self):
+ self.check_wrapper_attrs(staticmethod, '<staticmethod({!r})>')
+
+ def test_classmethod(self):
+ self.check_wrapper_attrs(classmethod, '<classmethod({!r})>')
def test_dotted(self):
decorators = MiscDecorators()
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 8c75ec3..79d6c4b 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1545,7 +1545,9 @@ order (MRO) for bases """
self.assertEqual(d.foo(1), (d, 1))
self.assertEqual(D.foo(d, 1), (d, 1))
# Test for a specific crash (SF bug 528132)
- def f(cls, arg): return (cls, arg)
+ def f(cls, arg):
+ "f docstring"
+ return (cls, arg)
ff = classmethod(f)
self.assertEqual(ff.__get__(0, int)(42), (int, 42))
self.assertEqual(ff.__get__(0)(42), (int, 42))
@@ -1571,10 +1573,16 @@ order (MRO) for bases """
self.fail("classmethod shouldn't accept keyword args")
cm = classmethod(f)
- self.assertEqual(cm.__dict__, {})
+ cm_dict = {'__annotations__': {},
+ '__doc__': "f docstring",
+ '__module__': __name__,
+ '__name__': 'f',
+ '__qualname__': f.__qualname__}
+ self.assertEqual(cm.__dict__, cm_dict)
+
cm.x = 42
self.assertEqual(cm.x, 42)
- self.assertEqual(cm.__dict__, {"x" : 42})
+ self.assertEqual(cm.__dict__, {"x" : 42, **cm_dict})
del cm.x
self.assertNotHasAttr(cm, "x")
@@ -1654,10 +1662,10 @@ order (MRO) for bases """
self.assertEqual(d.foo(1), (d, 1))
self.assertEqual(D.foo(d, 1), (d, 1))
sm = staticmethod(None)
- self.assertEqual(sm.__dict__, {})
+ self.assertEqual(sm.__dict__, {'__doc__': None})
sm.x = 42
self.assertEqual(sm.x, 42)
- self.assertEqual(sm.__dict__, {"x" : 42})
+ self.assertEqual(sm.__dict__, {"x" : 42, '__doc__': None})
del sm.x
self.assertNotHasAttr(sm, "x")
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index 61575b5..e94ebd3 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -1142,7 +1142,8 @@ class TestDescriptions(unittest.TestCase):
'''A static method'''
...
self.assertEqual(self._get_summary_lines(X.__dict__['sm']),
- "<staticmethod object>")
+ 'sm(...)\n'
+ ' A static method\n')
self.assertEqual(self._get_summary_lines(X.sm), """\
sm(x, y)
A static method
@@ -1162,7 +1163,8 @@ sm(x, y)
'''A class method'''
...
self.assertEqual(self._get_summary_lines(X.__dict__['cm']),
- "<classmethod object>")
+ 'cm(...)\n'
+ ' A class method\n')
self.assertEqual(self._get_summary_lines(X.cm), """\
cm(x) method of builtins.type instance
A class method
diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py
index a328810..0555b71 100644
--- a/Lib/test/test_reprlib.py
+++ b/Lib/test/test_reprlib.py
@@ -203,9 +203,9 @@ class ReprTests(unittest.TestCase):
class C:
def foo(cls): pass
x = staticmethod(C.foo)
- self.assertTrue(repr(x).startswith('<staticmethod object at 0x'))
+ self.assertEqual(repr(x), f'<staticmethod({C.foo!r})>')
x = classmethod(C.foo)
- self.assertTrue(repr(x).startswith('<classmethod object at 0x'))
+ self.assertEqual(repr(x), f'<classmethod({C.foo!r})>')
def test_unsortable(self):
# Repr.repr() used to call sorted() on sets, frozensets and dicts