Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add autosummary_filename_map config to avoid clashes #7927

Merged
merged 8 commits into from Jul 23, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/usage/extensions/autosummary.rst
Expand Up @@ -195,6 +195,15 @@ also use these config values:

.. versionadded:: 2.1

.. confval:: autosummary_filename_map

A dict mapping object names to filenames. This is necessary to avoid
filename conflicts where multiple objects have names that are
indistinguishable when case is ignored, on file systems where filenames
are case-insensitive.

.. versionadded:: 3.2


Customizing templates
---------------------
Expand Down
1 change: 1 addition & 0 deletions sphinx/ext/autosummary/__init__.py
Expand Up @@ -790,5 +790,6 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('autosummary_mock_imports',
lambda config: config.autodoc_mock_imports, 'env')
app.add_config_value('autosummary_imported_members', [], False, [bool])
app.add_config_value('autosummary_filename_map', {}, 'html')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to add a new config variable alphabetically. Could you move this above?
(I noticed autosummary_imported_members is not. I'll fix it later)


return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
13 changes: 11 additions & 2 deletions sphinx/ext/autosummary/generate.py
Expand Up @@ -28,7 +28,7 @@
import warnings
from gettext import NullTranslations
from os import path
from typing import Any, Callable, Dict, List, NamedTuple, Set, Tuple, Union
from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Set, Tuple, Union

from jinja2 import TemplateNotFound
from jinja2.sandbox import SandboxedEnvironment
Expand Down Expand Up @@ -74,6 +74,7 @@ def __init__(self, translator: NullTranslations) -> None:
self.warningiserror = False

self.config.add('autosummary_context', {}, True, None)
self.config.add('autosummary_filename_map', {}, True, None)
tk0miya marked this conversation as resolved.
Show resolved Hide resolved
self.config.init_values()

def emit_firstresult(self, *args: Any) -> None:
Expand Down Expand Up @@ -393,6 +394,14 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
# keep track of new files
new_files = []

if app:
filename_map = app.config.autosummary_filename_map
if not isinstance(filename_map, Mapping):
raise TypeError('autosummary_filename_map should be a mapping from '
'strings to strings')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to check the value is dict here. The Sphinx automatically checks the given value is the same type as the default value. But it does not check the contents of the dict. I think the default check is enough.

Note: If you'd like to add more careful validations, please use a hook for the config-inited event to validate user configurations.

def validate_latex_theme_options(app: Sphinx, config: Config) -> None:
for key in list(config.latex_theme_options):
if key not in Theme.UPDATABLE_KEYS:
msg = __("Unknown theme option: latex_theme_options[%r], ignored.")
logger.warning(msg % (key,))
config.latex_theme_options.pop(key)

app.connect('config-inited', validate_latex_theme_options, priority=800)

else:
filename_map = {}

# write
for entry in sorted(set(items), key=str):
if entry.path is None:
Expand All @@ -418,7 +427,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
imported_members, app, entry.recursive, context,
modname, qualname)

filename = os.path.join(path, name + suffix)
filename = os.path.join(path, filename_map.get(name, name) + suffix)
if os.path.isfile(filename):
with open(filename, encoding=encoding) as f:
old_content = f.read()
Expand Down
@@ -0,0 +1,21 @@
from os import path # NOQA
from typing import Union


class Foo:
class Bar:
pass

def __init__(self):
pass

def bar(self):
pass

@property
def baz(self):
pass


def bar(x: Union[int, str], y: int = 1) -> None:
pass
11 changes: 11 additions & 0 deletions tests/roots/test-ext-autosummary-filename-map/conf.py
@@ -0,0 +1,11 @@
import os
import sys

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

extensions = ['sphinx.ext.autosummary']
autosummary_generate = True
autosummary_filename_map = {
"autosummary_dummy_module": "module_mangled",
"autosummary_dummy_module.bar": "bar"
}
14 changes: 14 additions & 0 deletions tests/roots/test-ext-autosummary-filename-map/index.rst
@@ -0,0 +1,14 @@

:autolink:`autosummary_dummy_module.Foo`

:autolink:`autosummary_importfail`
tk0miya marked this conversation as resolved.
Show resolved Hide resolved

.. autosummary::
:toctree: generated
:caption: An autosummary

autosummary_dummy_module
autosummary_dummy_module.Foo
autosummary_dummy_module.Foo.Bar
autosummary_dummy_module.bar
autosummary_dummy_module.qux
11 changes: 11 additions & 0 deletions tests/test_ext_autosummary.py
Expand Up @@ -386,6 +386,17 @@ def test_autosummary_recursive(app, status, warning):
assert 'package.package.module' in content


@pytest.mark.sphinx('dummy', testroot='ext-autosummary-filename-map')
def test_autosummary_filename_map(app, status, warning):
app.build()

assert (app.srcdir / 'generated' / 'module_mangled.rst').exists()
assert not (app.srcdir / 'generated' / 'autosummary_dummy_module.rst').exists()
assert (app.srcdir / 'generated' / 'bar.rst').exists()
assert not (app.srcdir / 'generated' / 'autosummary_dummy_module.bar.rst').exists()
assert (app.srcdir / 'generated' / 'autosummary_dummy_module.Foo.rst').exists()


@pytest.mark.sphinx('latex', **default_kw)
def test_autosummary_latex_table_colspec(app, status, warning):
app.builder.build_all()
Expand Down