cls = _findclass(obj.fget)
if cls is None or getattr(cls, name) is not obj:
return None
+ # Should be tested before ismethoddescriptor()
+ elif isinstance(obj, functools.cached_property):
+ name = obj.attrname
+ cls = _findclass(obj.func)
+ if cls is None or getattr(cls, name) is not obj:
+ return None
elif ismethoddescriptor(obj) or isdatadescriptor(obj):
name = obj.__name__
cls = obj.__objclass__
--- /dev/null
+from functools import cached_property
+
+# docstring in parent, inherited in child
+class ParentInheritDoc:
+ @cached_property
+ def foo(self):
+ """docstring for foo defined in parent"""
+
+class ChildInheritDoc(ParentInheritDoc):
+ pass
+
+class ChildInheritDefineDoc(ParentInheritDoc):
+ @cached_property
+ def foo(self):
+ pass
+
+# Redefine foo as something other than cached_property
+class ChildPropertyFoo(ParentInheritDoc):
+ @property
+ def foo(self):
+ """docstring for the property foo"""
+
+class ChildMethodFoo(ParentInheritDoc):
+ def foo(self):
+ """docstring for the method foo"""
+
+# docstring in child but not parent
+class ParentNoDoc:
+ @cached_property
+ def foo(self):
+ pass
+
+class ChildNoDoc(ParentNoDoc):
+ pass
+
+class ChildDefineDoc(ParentNoDoc):
+ @cached_property
+ def foo(self):
+ """docstring for foo defined in child"""
from test.test_inspect import inspect_fodder as mod
from test.test_inspect import inspect_fodder2 as mod2
+from test.test_inspect import inspect_fodder3 as mod3
from test.test_inspect import inspect_stringized_annotations
from test.test_inspect import inspect_deferred_annotations
b.__doc__ = 'Instance'
self.assertEqual(inspect.getdoc(b, fallback_to_class_doc=False), 'Instance')
+ def test_getdoc_inherited_cached_property(self):
+ doc = inspect.getdoc(mod3.ParentInheritDoc.foo)
+ self.assertEqual(doc, 'docstring for foo defined in parent')
+ self.assertEqual(inspect.getdoc(mod3.ChildInheritDoc.foo), doc)
+ self.assertEqual(inspect.getdoc(mod3.ChildInheritDefineDoc.foo), doc)
+
+ def test_getdoc_redefine_cached_property_as_other(self):
+ self.assertEqual(inspect.getdoc(mod3.ChildPropertyFoo.foo),
+ 'docstring for the property foo')
+ self.assertEqual(inspect.getdoc(mod3.ChildMethodFoo.foo),
+ 'docstring for the method foo')
+
+ def test_getdoc_define_cached_property(self):
+ self.assertEqual(inspect.getdoc(mod3.ChildDefineDoc.foo),
+ 'docstring for foo defined in child')
+
+ def test_getdoc_nodoc_inherited(self):
+ self.assertIsNone(inspect.getdoc(mod3.ChildNoDoc.foo))
+
@unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
def test_finddoc(self):
finddoc = inspect._finddoc