diff options
| author | Clément Pinard <clempinard@gmail.com> | 2023-04-06 01:02:37 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-06 00:02:37 +0100 |
| commit | 9299003d40c775150c53366dcfdd4d944d0da1af (patch) | |
| tree | ca6bb2c9b8130a2c6ce71d962007361b66550b1a /sphinx/ext | |
| parent | 52a099b7ec9b08aa034c05c515d7ba5e6f7b004c (diff) | |
| download | sphinx-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.py | 52 |
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'] = \ |
