summaryrefslogtreecommitdiff
path: root/sphinx/ext
diff options
context:
space:
mode:
authorClément Pinard <clempinard@gmail.com>2023-04-06 01:02:37 +0200
committerGitHub <noreply@github.com>2023-04-06 00:02:37 +0100
commit9299003d40c775150c53366dcfdd4d944d0da1af (patch)
treeca6bb2c9b8130a2c6ce71d962007361b66550b1a /sphinx/ext
parent52a099b7ec9b08aa034c05c515d7ba5e6f7b004c (diff)
downloadsphinx-git-9299003d40c775150c53366dcfdd4d944d0da1af.tar.gz
Autosummary: Extend ``__all__`` members to template rendering (#10811)
When ``False``, the ``autosummary_ignore_module_all`` option adds members to the module's members entry that will be used for autodoc, but otherwise ignores it. As such, if a class is available in the ``__all__``, it won't be generated. This commit aims to extend the ``__all__`` handling not only to members, but also to corresponding attribute types (function, classes, exceptions, modules) The ``imported_members`` option is set to ``True`` if the object has an ``__all__`` member and ``autosummary_ignore_module_all`` is ``False``
Diffstat (limited to 'sphinx/ext')
-rw-r--r--sphinx/ext/autosummary/generate.py52
1 files changed, 49 insertions, 3 deletions
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index 9b9abdf26..b74ce0142 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -300,9 +300,17 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
pass # give up if ModuleAnalyzer fails to parse code
return public, attrs
- def get_modules(obj: Any) -> tuple[list[str], list[str]]:
+ def get_modules(
+ obj: Any,
+ skip: Sequence[str],
+ public_members: Sequence[str] | None = None) -> tuple[list[str], list[str]]:
items: list[str] = []
+ public: list[str] = []
for _, modname, _ispkg in pkgutil.iter_modules(obj.__path__):
+
+ if modname in skip:
+ # module was overwritten in __init__.py, so not accessible
+ continue
fullname = name + '.' + modname
try:
module = import_module(fullname)
@@ -312,7 +320,12 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
pass
items.append(fullname)
- public = [x for x in items if not x.split('.')[-1].startswith('_')]
+ if public_members is not None:
+ if modname in public_members:
+ public.append(fullname)
+ else:
+ if not modname.startswith('_'):
+ public.append(fullname)
return public, items
ns: dict[str, Any] = {}
@@ -321,6 +334,10 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
if doc.objtype == 'module':
scanner = ModuleScanner(app, obj)
ns['members'] = scanner.scan(imported_members)
+
+ respect_module_all = not app.config.autosummary_ignore_module_all
+ imported_members = imported_members or ('__all__' in dir(obj) and respect_module_all)
+
ns['functions'], ns['all_functions'] = \
get_members(obj, {'function'}, imported=imported_members)
ns['classes'], ns['all_classes'] = \
@@ -331,7 +348,36 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
get_module_attrs(ns['members'])
ispackage = hasattr(obj, '__path__')
if ispackage and recursive:
- ns['modules'], ns['all_modules'] = get_modules(obj)
+ # Use members that are not modules as skip list, because it would then mean
+ # that module was overwritten in the package namespace
+ skip = (
+ ns["all_functions"]
+ + ns["all_classes"]
+ + ns["all_exceptions"]
+ + ns["all_attributes"]
+ )
+
+ # If respect_module_all and module has a __all__ attribute, first get
+ # modules that were explicitly imported. Next, find the rest with the
+ # get_modules method, but only put in "public" modules that are in the
+ # __all__ list
+ #
+ # Otherwise, use get_modules method normally
+ if respect_module_all and '__all__' in dir(obj):
+ imported_modules, all_imported_modules = \
+ get_members(obj, {'module'}, imported=True)
+ skip += all_imported_modules
+ imported_modules = [name + '.' + modname for modname in imported_modules]
+ all_imported_modules = \
+ [name + '.' + modname for modname in all_imported_modules]
+ public_members = getall(obj)
+ else:
+ imported_modules, all_imported_modules = [], []
+ public_members = None
+
+ modules, all_modules = get_modules(obj, skip=skip, public_members=public_members)
+ ns['modules'] = imported_modules + modules
+ ns["all_modules"] = all_imported_modules + all_modules
elif doc.objtype == 'class':
ns['members'] = dir(obj)
ns['inherited_members'] = \