mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Close #5923: autodoc: allow not to document inherited members of specific super class
This commit is contained in:
parent
9d39b187c1
commit
7c79a6b8d1
4
CHANGES
4
CHANGES
@ -14,6 +14,8 @@ Incompatible changes
|
|||||||
* Drop features and APIs deprecated in 1.8.x
|
* Drop features and APIs deprecated in 1.8.x
|
||||||
* #247: autosummary: stub files are overwritten automatically by default. see
|
* #247: autosummary: stub files are overwritten automatically by default. see
|
||||||
:confval:`autosummary_generate_overwrite` to change the behavior
|
:confval:`autosummary_generate_overwrite` to change the behavior
|
||||||
|
* #5923: autodoc: the members of ``object`` class are not documented by default
|
||||||
|
when ``:inherited-members:`` and ``:special-members:`` are given.
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
@ -23,6 +25,8 @@ Features added
|
|||||||
|
|
||||||
* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite
|
* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite
|
||||||
old stub file
|
old stub file
|
||||||
|
* #5923: autodoc: ``:inherited-members:`` option takes a name of anchestor class
|
||||||
|
not to document inherited members of the class and uppers
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
@ -157,7 +157,7 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
|
|
||||||
* For classes and exceptions, members inherited from base classes will be
|
* For classes and exceptions, members inherited from base classes will be
|
||||||
left out when documenting all members, unless you give the
|
left out when documenting all members, unless you give the
|
||||||
``inherited-members`` flag option, in addition to ``members``::
|
``inherited-members`` option, in addition to ``members``::
|
||||||
|
|
||||||
.. autoclass:: Noodle
|
.. autoclass:: Noodle
|
||||||
:members:
|
:members:
|
||||||
@ -166,11 +166,19 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
|
|||||||
This can be combined with ``undoc-members`` to document *all* available
|
This can be combined with ``undoc-members`` to document *all* available
|
||||||
members of the class or module.
|
members of the class or module.
|
||||||
|
|
||||||
|
It can take an anchestor class not to document inherited members from it.
|
||||||
|
By default, members of ``object`` class are not documented. To show them
|
||||||
|
all, give ``None`` to the option.
|
||||||
|
|
||||||
Note: this will lead to markup errors if the inherited members come from a
|
Note: this will lead to markup errors if the inherited members come from a
|
||||||
module whose docstrings are not reST formatted.
|
module whose docstrings are not reST formatted.
|
||||||
|
|
||||||
.. versionadded:: 0.3
|
.. versionadded:: 0.3
|
||||||
|
|
||||||
|
.. versionchanged:: 3.0
|
||||||
|
|
||||||
|
It takes an anchestor class name as an argument.
|
||||||
|
|
||||||
* It's possible to override the signature for explicitly documented callable
|
* It's possible to override the signature for explicitly documented callable
|
||||||
objects (functions, methods, classes) with the regular syntax that will
|
objects (functions, methods, classes) with the regular syntax that will
|
||||||
override the signature gained from introspection::
|
override the signature gained from introspection::
|
||||||
|
@ -82,6 +82,14 @@ def members_set_option(arg: Any) -> Union[object, Set[str]]:
|
|||||||
return {x.strip() for x in arg.split(',')}
|
return {x.strip() for x in arg.split(',')}
|
||||||
|
|
||||||
|
|
||||||
|
def inherited_members_option(arg: Any) -> Union[object, Set[str]]:
|
||||||
|
"""Used to convert the :members: option to auto directives."""
|
||||||
|
if arg is None:
|
||||||
|
return 'object'
|
||||||
|
else:
|
||||||
|
return arg
|
||||||
|
|
||||||
|
|
||||||
SUPPRESS = object()
|
SUPPRESS = object()
|
||||||
|
|
||||||
|
|
||||||
@ -515,6 +523,17 @@ class Documenter:
|
|||||||
The user can override the skipping decision by connecting to the
|
The user can override the skipping decision by connecting to the
|
||||||
``autodoc-skip-member`` event.
|
``autodoc-skip-member`` event.
|
||||||
"""
|
"""
|
||||||
|
def is_filtered_inherited_member(name: str) -> bool:
|
||||||
|
if inspect.isclass(self.object):
|
||||||
|
for cls in self.object.__mro__:
|
||||||
|
if cls.__name__ == self.options.inherited_members and cls != self.object:
|
||||||
|
# given member is a member of specified *super class*
|
||||||
|
return True
|
||||||
|
elif name in cls.__dict__:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
ret = []
|
ret = []
|
||||||
|
|
||||||
# search for members in source code too
|
# search for members in source code too
|
||||||
@ -545,12 +564,15 @@ class Documenter:
|
|||||||
if want_all and membername.startswith('__') and \
|
if want_all and membername.startswith('__') and \
|
||||||
membername.endswith('__') and len(membername) > 4:
|
membername.endswith('__') and len(membername) > 4:
|
||||||
# special __methods__
|
# special __methods__
|
||||||
if self.options.special_members is ALL and \
|
if self.options.special_members is ALL:
|
||||||
membername != '__doc__':
|
if membername == '__doc__':
|
||||||
|
keep = False
|
||||||
|
elif is_filtered_inherited_member(membername):
|
||||||
|
keep = False
|
||||||
|
else:
|
||||||
keep = has_doc or self.options.undoc_members
|
keep = has_doc or self.options.undoc_members
|
||||||
elif self.options.special_members and \
|
elif self.options.special_members:
|
||||||
self.options.special_members is not ALL and \
|
if membername in self.options.special_members:
|
||||||
membername in self.options.special_members:
|
|
||||||
keep = has_doc or self.options.undoc_members
|
keep = has_doc or self.options.undoc_members
|
||||||
elif (namespace, membername) in attr_docs:
|
elif (namespace, membername) in attr_docs:
|
||||||
if want_all and membername.startswith('_'):
|
if want_all and membername.startswith('_'):
|
||||||
@ -564,6 +586,9 @@ class Documenter:
|
|||||||
# ignore members whose name starts with _ by default
|
# ignore members whose name starts with _ by default
|
||||||
keep = self.options.private_members and \
|
keep = self.options.private_members and \
|
||||||
(has_doc or self.options.undoc_members)
|
(has_doc or self.options.undoc_members)
|
||||||
|
else:
|
||||||
|
if self.options.members is ALL and is_filtered_inherited_member(membername):
|
||||||
|
keep = False
|
||||||
else:
|
else:
|
||||||
# ignore undocumented members if :undoc-members: is not given
|
# ignore undocumented members if :undoc-members: is not given
|
||||||
keep = has_doc or self.options.undoc_members
|
keep = has_doc or self.options.undoc_members
|
||||||
@ -740,7 +765,7 @@ class ModuleDocumenter(Documenter):
|
|||||||
|
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'members': members_option, 'undoc-members': bool_option,
|
'members': members_option, 'undoc-members': bool_option,
|
||||||
'noindex': bool_option, 'inherited-members': bool_option,
|
'noindex': bool_option, 'inherited-members': inherited_members_option,
|
||||||
'show-inheritance': bool_option, 'synopsis': identity,
|
'show-inheritance': bool_option, 'synopsis': identity,
|
||||||
'platform': identity, 'deprecated': bool_option,
|
'platform': identity, 'deprecated': bool_option,
|
||||||
'member-order': identity, 'exclude-members': members_set_option,
|
'member-order': identity, 'exclude-members': members_set_option,
|
||||||
@ -1039,7 +1064,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
member_order = 20
|
member_order = 20
|
||||||
option_spec = {
|
option_spec = {
|
||||||
'members': members_option, 'undoc-members': bool_option,
|
'members': members_option, 'undoc-members': bool_option,
|
||||||
'noindex': bool_option, 'inherited-members': bool_option,
|
'noindex': bool_option, 'inherited-members': inherited_members_option,
|
||||||
'show-inheritance': bool_option, 'member-order': identity,
|
'show-inheritance': bool_option, 'member-order': identity,
|
||||||
'exclude-members': members_set_option,
|
'exclude-members': members_set_option,
|
||||||
'private-members': bool_option, 'special-members': members_option,
|
'private-members': bool_option, 'special-members': members_option,
|
||||||
|
@ -581,6 +581,30 @@ def test_autodoc_inherited_members(app):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autodoc_inherited_members_Base(app):
|
||||||
|
options = {"members": None,
|
||||||
|
"inherited-members": "Base",
|
||||||
|
"special-members": None}
|
||||||
|
|
||||||
|
# check methods for object class are shown
|
||||||
|
actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
|
||||||
|
assert ' .. py:method:: Derived.inheritedmeth()' in actual
|
||||||
|
assert ' .. py:method:: Derived.inheritedclassmeth' not in actual
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
|
def test_autodoc_inherited_members_None(app):
|
||||||
|
options = {"members": None,
|
||||||
|
"inherited-members": "None",
|
||||||
|
"special-members": None}
|
||||||
|
|
||||||
|
# check methods for object class are shown
|
||||||
|
actual = do_autodoc(app, 'class', 'target.inheritance.Derived', options)
|
||||||
|
assert ' .. py:method:: Derived.__init__' in actual
|
||||||
|
assert ' .. py:method:: Derived.__str__' in actual
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_autodoc_imported_members(app):
|
def test_autodoc_imported_members(app):
|
||||||
options = {"members": None,
|
options = {"members": None,
|
||||||
|
Loading…
Reference in New Issue
Block a user