From e61f56950d624f5fa540a1c8d4e3baedd2889bd0 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Wed, 17 Jul 2024 21:42:21 +0100 Subject: [PATCH] Do not add the module prefix when generating autosummary documents (#12609) --- CHANGES.rst | 3 ++ sphinx/ext/autosummary/generate.py | 17 +++++------ .../templates/autosummary/module.rst | 28 +++++++++---------- sphinx/project.py | 6 ++-- .../conf.py | 8 ++++++ .../index.rst | 5 ++++ .../pkg/__init__.py | 0 .../pkg/mod0/__init__.py | 0 .../pkg/mod1/__init__.py | 0 tests/test_extensions/test_ext_autosummary.py | 22 ++++++++++----- .../test_ext_autosummary_imports.py | 9 ++++++ 11 files changed, 65 insertions(+), 33 deletions(-) create mode 100644 tests/roots/test-ext-autosummary-module_prefix/conf.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/index.rst create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py create mode 100644 tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py diff --git a/CHANGES.rst b/CHANGES.rst index 7b4cd5848bf..a77bb761d79 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ Release 7.4.6 (in development) Bugs fixed ---------- +* #12859, #9743, #12609: autosummary: Do not add the package prefix when + generating autosummary directives for modules within a package. + Patch by Adam Turner. Release 7.4.5 (released Jul 16, 2024) ===================================== diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index d434d39f846..f4b0df04e3b 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -330,10 +330,6 @@ def generate_autosummary_content( doc, app, 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 = [], [] @@ -476,21 +472,22 @@ def _get_modules( if modname in skip: # module was overwritten in __init__.py, so not accessible continue - fullname = name + '.' + modname + fullname = f'{name}.{modname}' try: module = import_module(fullname) - if module and hasattr(module, '__sphinx_mock__'): - continue except ImportError: pass + else: + if module and hasattr(module, '__sphinx_mock__'): + continue - items.append(fullname) + items.append(modname) if public_members is not None: if modname in public_members: - public.append(fullname) + public.append(modname) else: if not modname.startswith('_'): - public.append(fullname) + public.append(modname) return public, items diff --git a/sphinx/ext/autosummary/templates/autosummary/module.rst b/sphinx/ext/autosummary/templates/autosummary/module.rst index e74c012f433..3ff0de9ed08 100644 --- a/sphinx/ext/autosummary/templates/autosummary/module.rst +++ b/sphinx/ext/autosummary/templates/autosummary/module.rst @@ -3,7 +3,7 @@ .. automodule:: {{ fullname }} {% block attributes %} - {% if attributes %} + {%- if attributes %} .. rubric:: {{ _('Module Attributes') }} .. autosummary:: @@ -11,10 +11,10 @@ {{ item }} {%- endfor %} {% endif %} - {% endblock %} + {%- endblock %} - {% block functions %} - {% if functions %} + {%- block functions %} + {%- if functions %} .. rubric:: {{ _('Functions') }} .. autosummary:: @@ -22,10 +22,10 @@ {{ item }} {%- endfor %} {% endif %} - {% endblock %} + {%- endblock %} - {% block classes %} - {% if classes %} + {%- block classes %} + {%- if classes %} .. rubric:: {{ _('Classes') }} .. autosummary:: @@ -33,10 +33,10 @@ {{ item }} {%- endfor %} {% endif %} - {% endblock %} + {%- endblock %} - {% block exceptions %} - {% if exceptions %} + {%- block exceptions %} + {%- if exceptions %} .. rubric:: {{ _('Exceptions') }} .. autosummary:: @@ -44,10 +44,10 @@ {{ item }} {%- endfor %} {% endif %} - {% endblock %} + {%- endblock %} -{% block modules %} -{% if modules %} +{%- block modules %} +{%- if modules %} .. rubric:: Modules .. autosummary:: @@ -57,4 +57,4 @@ {{ item }} {%- endfor %} {% endif %} -{% endblock %} +{%- endblock %} diff --git a/sphinx/project.py b/sphinx/project.py index 0ac9f1e9491..4a0fa1487a5 100644 --- a/sphinx/project.py +++ b/sphinx/project.py @@ -5,12 +5,13 @@ import contextlib import os from glob import glob +from pathlib import Path from typing import TYPE_CHECKING from sphinx.locale import __ from sphinx.util import logging from sphinx.util.matching import get_matching_files -from sphinx.util.osutil import path_stabilize, relpath +from sphinx.util.osutil import os_path, path_stabilize, relpath if TYPE_CHECKING: from collections.abc import Iterable @@ -24,7 +25,7 @@ class Project: def __init__(self, srcdir: str | os.PathLike[str], source_suffix: Iterable[str]) -> None: #: Source directory. - self.srcdir = srcdir + self.srcdir = Path(srcdir) #: source_suffix. Same as :confval:`source_suffix`. self.source_suffix = tuple(source_suffix) @@ -114,6 +115,7 @@ def doc2path(self, docname: str, absolute: bool) -> str: # Backwards compatibility: the document does not exist filename = docname + self._first_source_suffix + filename = os_path(filename) if absolute: return os.path.join(self.srcdir, filename) return filename diff --git a/tests/roots/test-ext-autosummary-module_prefix/conf.py b/tests/roots/test-ext-autosummary-module_prefix/conf.py new file mode 100644 index 00000000000..1065b9112e8 --- /dev/null +++ b/tests/roots/test-ext-autosummary-module_prefix/conf.py @@ -0,0 +1,8 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) + +extensions = [ + 'sphinx.ext.autosummary', +] diff --git a/tests/roots/test-ext-autosummary-module_prefix/index.rst b/tests/roots/test-ext-autosummary-module_prefix/index.rst new file mode 100644 index 00000000000..fe0b13c435c --- /dev/null +++ b/tests/roots/test-ext-autosummary-module_prefix/index.rst @@ -0,0 +1,5 @@ +.. autosummary:: + :toctree: docs/pkg + :recursive: + + pkg diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/mod0/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py b/tests/roots/test-ext-autosummary-module_prefix/pkg/mod1/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/test_extensions/test_ext_autosummary.py b/tests/test_extensions/test_ext_autosummary.py index 1aa8f4afb25..e3f034c3bc0 100644 --- a/tests/test_extensions/test_ext_autosummary.py +++ b/tests/test_extensions/test_ext_autosummary.py @@ -506,12 +506,20 @@ def test_autosummary_recursive(app, status, warning): # Check content of recursively generated stub-files content = (app.srcdir / 'generated' / 'package.rst').read_text(encoding='utf8') - assert 'package.module' in content - assert 'package.package' in content - assert 'package.module_importfail' in content + assert 'module' in content + assert 'package' in content + assert 'module_importfail' in content + # we no longer generate fully-qualified module names. + assert 'package.module' not in content + assert 'package.package' not in content + assert 'package.module_importfail' not in content content = (app.srcdir / 'generated' / 'package.package.rst').read_text(encoding='utf8') - assert 'package.package.module' in content + assert 'module' in content + assert 'package.package.module' not in content + + warnings = app.warning.getvalue() + assert 'Summarised items should not include the current module.' not in warnings @pytest.mark.sphinx('dummy', testroot='ext-autosummary-recursive', @@ -599,11 +607,11 @@ def test_autosummary_imported_members(app, status, warning): assert (' .. autosummary::\n' ' \n' ' Bar\n' - ' \n' in module) + ' ' in module) assert (' .. autosummary::\n' ' \n' ' foo\n' - ' \n' in module) + ' ' in module) finally: sys.modules.pop('autosummary_dummy_package', None) @@ -627,7 +635,7 @@ def test_autosummary_module_all(app, status, warning): assert ('.. autosummary::\n' ' :toctree:\n' ' :recursive:\n\n' - ' autosummary_dummy_package_all.extra_dummy_module\n\n' in module) + ' extra_dummy_module\n' in module) finally: sys.modules.pop('autosummary_dummy_package_all', None) diff --git a/tests/test_extensions/test_ext_autosummary_imports.py b/tests/test_extensions/test_ext_autosummary_imports.py index 2ac99923f2a..7420c99f979 100644 --- a/tests/test_extensions/test_ext_autosummary_imports.py +++ b/tests/test_extensions/test_ext_autosummary_imports.py @@ -38,3 +38,12 @@ def test_autosummary_import_cycle(app, warning): "Replace 'spam.eggs.Ham' with 'Ham'." ) assert expected in app.warning.getvalue() + + +@pytest.mark.sphinx('dummy', testroot='ext-autosummary-module_prefix') +@pytest.mark.usefixtures("rollback_sysmodules") +def test_autosummary_generate_prefixes(app, warning): + app.build() + warnings = app.warning.getvalue() + assert 'Summarised items should not include the current module.' not in warnings + assert warnings == ''