mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #10539 from AA-Turner/fix-inherited-attrs
Fix inherited attribute docstrings
This commit is contained in:
@@ -1670,7 +1670,8 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename)
|
||||
|
||||
def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:
|
||||
members = get_class_members(self.object, self.objpath, self.get_attr)
|
||||
members = get_class_members(self.object, self.objpath, self.get_attr,
|
||||
self.config.autodoc_inherit_docstrings)
|
||||
if not want_all:
|
||||
if not self.options.members:
|
||||
return False, [] # type: ignore
|
||||
|
||||
@@ -205,8 +205,8 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
|
||||
return members
|
||||
|
||||
|
||||
def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable
|
||||
) -> Dict[str, "ObjectMember"]:
|
||||
def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable,
|
||||
inherit_docstrings: bool = True) -> Dict[str, "ObjectMember"]:
|
||||
"""Get members and attributes of target class."""
|
||||
from sphinx.ext.autodoc import INSTANCEATTR, ObjectMember
|
||||
|
||||
@@ -290,6 +290,11 @@ def get_class_members(subject: Any, objpath: List[str], attrgetter: Callable
|
||||
elif (ns == qualname and docstring and
|
||||
isinstance(members[name], ObjectMember) and
|
||||
not members[name].docstring):
|
||||
if cls != subject and not inherit_docstrings:
|
||||
# If we are in the MRO of the class and not the class itself,
|
||||
# and we do not want to inherit docstrings, then skip setting
|
||||
# the docstring below
|
||||
continue
|
||||
# attribute is already known, because dir(subject) enumerates it.
|
||||
# But it has no docstring yet
|
||||
members[name].docstring = '\n'.join(docstring)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
class Base(object):
|
||||
#: docstring
|
||||
inheritedattr = None
|
||||
|
||||
def inheritedmeth(self):
|
||||
"""Inherited function."""
|
||||
|
||||
|
||||
@@ -549,6 +549,7 @@ def test_autodoc_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
' .. py:method:: Base.inheritedmeth()',
|
||||
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||
@@ -569,6 +570,7 @@ def test_autodoc_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
' .. py:method:: Base.inheritedmeth()',
|
||||
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||
@@ -601,6 +603,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()'
|
||||
]
|
||||
|
||||
@@ -618,6 +621,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()'
|
||||
]
|
||||
|
||||
@@ -628,6 +632,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||
]
|
||||
@@ -639,6 +644,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
]
|
||||
|
||||
@@ -648,6 +654,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
]
|
||||
|
||||
@@ -658,6 +665,7 @@ def test_autodoc_exclude_members(app):
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Base', options)
|
||||
assert list(filter(lambda l: '::' in l, actual)) == [
|
||||
'.. py:class:: Base()',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
' .. py:method:: Base.inheritedmeth()',
|
||||
' .. py:method:: Base.inheritedstaticmeth(cls)'
|
||||
|
||||
@@ -133,6 +133,13 @@ def test_automodule_inherited_members(app):
|
||||
' :module: target.inheritance',
|
||||
'',
|
||||
'',
|
||||
' .. py:attribute:: Base.inheritedattr',
|
||||
' :module: target.inheritance',
|
||||
' :value: None',
|
||||
'',
|
||||
' docstring',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Base.inheritedclassmeth()',
|
||||
' :module: target.inheritance',
|
||||
' :classmethod:',
|
||||
|
||||
@@ -277,6 +277,72 @@ def test_autodoc_inherit_docstrings(app):
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_inherit_docstrings_for_inherited_members(app):
|
||||
options = {"members": None,
|
||||
"inherited-members": None}
|
||||
|
||||
assert app.config.autodoc_inherit_docstrings is True # default
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:class:: Derived()',
|
||||
' :module: target.inheritance',
|
||||
'',
|
||||
'',
|
||||
' .. py:attribute:: Derived.inheritedattr',
|
||||
' :module: target.inheritance',
|
||||
' :value: None',
|
||||
'',
|
||||
' docstring',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Derived.inheritedclassmeth()',
|
||||
' :module: target.inheritance',
|
||||
' :classmethod:',
|
||||
'',
|
||||
' Inherited class method.',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Derived.inheritedmeth()',
|
||||
' :module: target.inheritance',
|
||||
'',
|
||||
' Inherited function.',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Derived.inheritedstaticmeth(cls)',
|
||||
' :module: target.inheritance',
|
||||
' :staticmethod:',
|
||||
'',
|
||||
' Inherited static method.',
|
||||
'',
|
||||
]
|
||||
|
||||
# disable autodoc_inherit_docstrings
|
||||
app.config.autodoc_inherit_docstrings = False
|
||||
actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
|
||||
assert list(actual) == [
|
||||
'',
|
||||
'.. py:class:: Derived()',
|
||||
' :module: target.inheritance',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Derived.inheritedclassmeth()',
|
||||
' :module: target.inheritance',
|
||||
' :classmethod:',
|
||||
'',
|
||||
' Inherited class method.',
|
||||
'',
|
||||
'',
|
||||
' .. py:method:: Derived.inheritedstaticmeth(cls)',
|
||||
' :module: target.inheritance',
|
||||
' :staticmethod:',
|
||||
'',
|
||||
' Inherited static method.',
|
||||
'',
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||
def test_autodoc_docstring_signature(app):
|
||||
options = {"members": None, "special-members": "__init__, __new__"}
|
||||
|
||||
Reference in New Issue
Block a user