Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
=====================================
Expand Down
17 changes: 7 additions & 10 deletions sphinx/ext/autosummary/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [], []
Expand Down Expand Up @@ -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


Expand Down
28 changes: 14 additions & 14 deletions sphinx/ext/autosummary/templates/autosummary/module.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,51 @@
.. automodule:: {{ fullname }}

{% block attributes %}
{% if attributes %}
{%- if attributes %}
.. rubric:: {{ _('Module Attributes') }}

.. autosummary::
{% for item in attributes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endblock %}

{% block functions %}
{% if functions %}
{%- block functions %}
{%- if functions %}
.. rubric:: {{ _('Functions') }}

.. autosummary::
{% for item in functions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endblock %}

{% block classes %}
{% if classes %}
{%- block classes %}
{%- if classes %}
.. rubric:: {{ _('Classes') }}

.. autosummary::
{% for item in classes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endblock %}

{% block exceptions %}
{% if exceptions %}
{%- block exceptions %}
{%- if exceptions %}
.. rubric:: {{ _('Exceptions') }}

.. autosummary::
{% for item in exceptions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endblock %}

{% block modules %}
{% if modules %}
{%- block modules %}
{%- if modules %}
.. rubric:: Modules

.. autosummary::
Expand All @@ -57,4 +57,4 @@
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endblock %}
6 changes: 4 additions & 2 deletions sphinx/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
8 changes: 8 additions & 0 deletions tests/roots/test-ext-autosummary-module_prefix/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import os
import sys

sys.path.insert(0, os.path.abspath('.'))

extensions = [
'sphinx.ext.autosummary',
]
5 changes: 5 additions & 0 deletions tests/roots/test-ext-autosummary-module_prefix/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.. autosummary::
:toctree: docs/pkg
:recursive:

pkg
Empty file.
Empty file.
Empty file.
22 changes: 15 additions & 7 deletions tests/test_extensions/test_ext_autosummary.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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)

Expand All @@ -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)

Expand Down
9 changes: 9 additions & 0 deletions tests/test_extensions/test_ext_autosummary_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 == ''