Skip to content

Commit

Permalink
Close sphinx-doc#8417: autodoc: :inherited-members: option now takes …
Browse files Browse the repository at this point in the history
…multiple classes

It allows to suppress inherited members of several classes on the module at
once by specifying the option to `automodule` directive
  • Loading branch information
tk0miya committed Apr 2, 2022
1 parent 633e079 commit 83f52d0
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGES
Expand Up @@ -58,6 +58,9 @@ Features added
* #9075: autodoc: The default value of :confval:`autodoc_typehints_format` is
changed to ``'smart'``. It will suppress the leading module names of
typehints (ex. ``io.StringIO`` -> ``StringIO``).
* #8417: autodoc: ``:inherited-members:`` option now takes multiple classes. It
allows to suppress inherited members of several classes on the module at once
by specifying the option to :rst:dir:`automodule` directive
* #10028: Removed internal usages of JavaScript frameworks (jQuery and
underscore.js) and modernised ``doctools.js`` and ``searchtools.js`` to
EMCAScript 2018.
Expand Down
10 changes: 7 additions & 3 deletions doc/usage/extensions/autodoc.rst
Expand Up @@ -252,9 +252,9 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
This can be combined with ``undoc-members`` to document *all* available
members of the class or module.

It can take an ancestor 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.
It can take a comma separated list of ancestor classes 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.

For example; If your class ``Foo`` is derived from ``list`` class and
you don't want to document ``list.__len__()``, you should specify a
Expand All @@ -275,6 +275,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,

It takes an ancestor class name as an argument.

.. versionchanged:: 5.0

It takes a comma separated list of ancestor class names.

* It's possible to override the signature for explicitly documented callable
objects (functions, methods, classes) with the regular syntax that will
override the signature gained from introspection::
Expand Down
12 changes: 8 additions & 4 deletions sphinx/ext/autodoc/__init__.py
Expand Up @@ -109,12 +109,14 @@ def exclude_members_option(arg: Any) -> Union[object, Set[str]]:
return {x.strip() for x in arg.split(',') if x.strip()}


def inherited_members_option(arg: Any) -> Union[object, Set[str]]:
def inherited_members_option(arg: Any) -> Set[str]:
"""Used to convert the :members: option to auto directives."""
if arg in (None, True):
return 'object'
return {'object'}
elif arg:
return set(x.strip() for x in arg.split(','))
else:
return arg
return set()


def member_order_option(arg: Any) -> Optional[str]:
Expand Down Expand Up @@ -680,9 +682,11 @@ def filter_members(self, members: ObjectMembers, want_all: bool
``autodoc-skip-member`` event.
"""
def is_filtered_inherited_member(name: str, obj: Any) -> bool:
inherited_members = self.options.inherited_members or set()

if inspect.isclass(self.object):
for cls in self.object.__mro__:
if cls.__name__ == self.options.inherited_members and cls != self.object:
if cls.__name__ in inherited_members and cls != self.object:
# given member is a member of specified *super class*
return True
elif name in cls.__dict__:
Expand Down
5 changes: 5 additions & 0 deletions tests/roots/test-ext-autodoc/target/inheritance.py
Expand Up @@ -15,3 +15,8 @@ class Derived(Base):
def inheritedmeth(self):
# no docstring here
pass


class MyList(list):
def meth(self):
"""docstring"""
57 changes: 57 additions & 0 deletions tests/test_ext_autodoc_automodule.py
Expand Up @@ -113,6 +113,63 @@ def test_automodule_special_members(app):
]


@pytest.mark.sphinx('html', testroot='ext-autodoc')
def test_automodule_inherited_members(app):
options = {'members': None,
'undoc-members': None,
'inherited-members': 'Base, list'}
actual = do_autodoc(app, 'module', 'target.inheritance', options)
assert list(actual) == [
'',
'.. py:module:: target.inheritance',
'',
'',
'.. py:class:: Base()',
' :module: target.inheritance',
'',
'',
' .. py:method:: Base.inheritedclassmeth()',
' :module: target.inheritance',
' :classmethod:',
'',
' Inherited class method.',
'',
'',
' .. py:method:: Base.inheritedmeth()',
' :module: target.inheritance',
'',
' Inherited function.',
'',
'',
' .. py:method:: Base.inheritedstaticmeth(cls)',
' :module: target.inheritance',
' :staticmethod:',
'',
' Inherited static method.',
'',
'',
'.. py:class:: Derived()',
' :module: target.inheritance',
'',
'',
' .. py:method:: Derived.inheritedmeth()',
' :module: target.inheritance',
'',
' Inherited function.',
'',
'',
'.. py:class:: MyList(iterable=(), /)',
' :module: target.inheritance',
'',
'',
' .. py:method:: MyList.meth()',
' :module: target.inheritance',
'',
' docstring',
'',
]


@pytest.mark.sphinx('html', testroot='ext-autodoc',
confoverrides={'autodoc_mock_imports': ['missing_module',
'missing_package1',
Expand Down

0 comments on commit 83f52d0

Please sign in to comment.