diff options
author | Victor Stinner <vstinner@python.org> | 2021-04-09 15:51:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-09 15:51:22 (GMT) |
commit | 507a574de31a1bd7fed8ba4f04afa285d985109b (patch) | |
tree | 44fb249533ae98698ef7736bc050df450f9a07e1 /Lib/test | |
parent | 150af7543214e1541fa582374502ac1cd70e8eb4 (diff) | |
download | cpython-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.py | 26 | ||||
-rw-r--r-- | Lib/test/test_descr.py | 18 | ||||
-rw-r--r-- | Lib/test/test_pydoc.py | 6 | ||||
-rw-r--r-- | Lib/test/test_reprlib.py | 4 |
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 |