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.
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 @@ class D(C):
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 @@ def f(cls, arg): return (cls, arg)
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 @@ class D(C):
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")