Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,9 @@ Retrieving source code
.. versionchanged:: 3.5
Documentation strings are now inherited if not overridden.

.. versionchanged:: next
Now correctly returns an inherited docstring on :class:`~functools.cached_property` objects if not overridden.


.. function:: getcomments(object)

Expand Down
6 changes: 6 additions & 0 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,12 @@ def _finddoc(obj):
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__
Expand Down
34 changes: 34 additions & 0 deletions Lib/test/test_inspect/inspect_fodder3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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):
@cached_property
def foo(self):
pass

# Redine foo as something other than cached_property
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Redine foo as something other than cached_property
# redefine foo as something other than cached_property

class ChildPropertyFoo(ParentInheritDoc):
@property
def foo(self):
"docstring for the property foo"
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pass


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 ChildDefineDoc(ParentNoDoc):
@cached_property
def foo(self):
"docstring for foo defined in child"
15 changes: 15 additions & 0 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

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

Expand Down Expand Up @@ -665,6 +666,20 @@ def test_getdoc_inherited(self):
self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
'The automatic gainsaying.')

def test_getdoc_inherited_cached_property(self):
self.assertEqual(inspect.getdoc(mod3.ChildInheritDoc.foo),
'docstring for foo defined in parent')

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')

@unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
def test_finddoc(self):
finddoc = inspect._finddoc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:func:`inspect.getdoc` now correctly returns an inherited docstring on :class:`~functools.cached_property` objects if none is given in a subclass.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
:func:`inspect.getdoc` now correctly returns an inherited docstring on :class:`~functools.cached_property` objects if none is given in a subclass.
:func:`inspect.getdoc` now correctly returns an inherited docstring on
:class:`~functools.cached_property` objects if none is given in a subclass.

Loading