Skip to content

Commit

Permalink
Fix sphinx-doc#247: autosummary: Add autosummary_generate_option to o…
Browse files Browse the repository at this point in the history
…verwrite old stub file
  • Loading branch information
tk0miya committed Jun 1, 2019
1 parent 172b5fb commit 5b50c8a
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 16 deletions.
4 changes: 3 additions & 1 deletion CHANGES
Expand Up @@ -90,8 +90,10 @@ Features added
autodoc considers values as a docstring of the attribute
* #6361: autodoc: Add :confval:`autodoc_typehints` to suppress typehints from
signature
* #6212 autosummary: Add :confval:`autosummary_imported_members` to display
* #6212: autosummary: Add :confval:`autosummary_imported_members` to display
imported members on autosummary
* #247: autosummary: Add :confval:`autosummary_generate_option` to overwrite
old stub file
* #6271: ``make clean`` is catastrophically broken if building into '.'
* #6363: Support ``%O%`` environment variable in make.bat
* #4777: py domain: Add ``:async:`` option to :rst:dir:`py:function` directive
Expand Down
10 changes: 10 additions & 0 deletions doc/usage/extensions/autosummary.rst
Expand Up @@ -143,6 +143,16 @@ also use these config values:
The new files will be placed in the directories specified in the
``:toctree:`` options of the directives.

.. confval:: autosummary_generate_option

This value switches the behavior when autosummary detects old stub files.

* ``'skip'`` -- Skip stub file generation (default)
* ``'warning'`` -- Emit a warning and skip generation
* ``'overwrite'`` -- Overwrite the stub file

.. versionadded:: 2.1

.. confval:: autosummary_mock_imports

This value contains a list of modules to be mocked up. See
Expand Down
6 changes: 5 additions & 1 deletion sphinx/ext/autosummary/__init__.py
Expand Up @@ -68,6 +68,7 @@

import sphinx
from sphinx import addnodes
from sphinx.config import ENUM
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.environment.adapters.toctree import TocTree
from sphinx.ext.autodoc import get_documenters
Expand Down Expand Up @@ -756,7 +757,8 @@ def process_generate_options(app):
generate_autosummary_docs(genfiles, builder=app.builder,
warn=logger.warning, info=logger.info,
suffix=suffix, base_path=app.srcdir,
app=app, imported_members=imported_members)
app=app, imported_members=imported_members,
generate_option=app.config.autosummary_generate_option)


def setup(app):
Expand All @@ -780,6 +782,8 @@ def setup(app):
app.connect('doctree-read', process_autosummary_toc)
app.connect('builder-inited', process_generate_options)
app.add_config_value('autosummary_generate', [], True, [bool])
app.add_config_value('autosummary_generate_option', 'skip', False,
ENUM('skip', 'warning', 'overwrite'))
app.add_config_value('autosummary_mock_imports',
lambda config: config.autodoc_mock_imports, 'env')
app.add_config_value('autosummary_imported_members', [], False, [bool])
Expand Down
40 changes: 26 additions & 14 deletions sphinx/ext/autosummary/generate.py
Expand Up @@ -196,8 +196,8 @@ def get_members(obj, types, include_public=[], imported=True):
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
warn=_simple_warn, info=_simple_info,
base_path=None, builder=None, template_dir=None,
imported_members=False, app=None):
# type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any) -> None
imported_members=False, app=None, generate_option='skip'):
# type: (List[str], str, str, Callable, Callable, str, Builder, str, bool, Any, str) -> None

showed_sources = list(sorted(sources))
if len(showed_sources) > 20:
Expand Down Expand Up @@ -235,26 +235,38 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
warn('[autosummary] failed to import %r: %s' % (name, e))
continue

fn = os.path.join(path, name + suffix)
content = generate_autosummary_content(name, obj, parent, template, template_name,
imported_members, app)

# skip it if it exists
if os.path.isfile(fn):
continue

new_files.append(fn)
filename = os.path.join(path, name + suffix)
if os.path.isfile(filename):
with open(filename) as f:
old_content = f.read()

with open(fn, 'w') as f:
rendered = generate_autosummary_content(name, obj, parent,
template, template_name,
imported_members, app)
f.write(rendered)
if content == old_content:
continue
else:
# content has changed
if generate_option == 'skip':
continue
elif generate_option == 'warning':
warn('[autosummary] %s has changed. Ignored.' % filename)
elif generate_option == 'overwrite':
with open(filename, 'w') as f:
f.write(content)
new_files.append(filename)
else:
with open(filename, 'w') as f:
f.write(content)
new_files.append(filename)

# descend recursively to new files
if new_files:
generate_autosummary_docs(new_files, output_dir=output_dir,
suffix=suffix, warn=warn, info=info,
base_path=base_path, builder=builder,
template_dir=template_dir, app=app)
template_dir=template_dir, app=app,
generate_option=generate_option)


# -- Finding documented entries in files ---------------------------------------
Expand Down
45 changes: 45 additions & 0 deletions tests/test_ext_autosummary.py
Expand Up @@ -222,6 +222,51 @@ def test_autosummary_generate(app, status, warning):
' \n' in Foo)


@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
confoverrides={'autosummary_generate_option': 'skip'})
def test_autosummary_generate_option_skip(app_params, make_app):
args, kwargs = app_params
srcdir = kwargs.get('srcdir')

(srcdir / 'generated').makedirs(exist_ok=True)
(srcdir / 'generated' / 'autosummary_dummy_module.rst').write_text('')

app = make_app(*args, **kwargs)
content = (srcdir / 'generated' / 'autosummary_dummy_module.rst').text()
assert content == ''
assert 'autosummary_dummy_module.rst' not in app._warning.getvalue()


@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
confoverrides={'autosummary_generate_option': 'warning'})
def test_autosummary_generate_option_warning(app_params, make_app):
args, kwargs = app_params
srcdir = kwargs.get('srcdir')

(srcdir / 'generated').makedirs(exist_ok=True)
(srcdir / 'generated' / 'autosummary_dummy_module.rst').write_text('')

app = make_app(*args, **kwargs)
content = (srcdir / 'generated' / 'autosummary_dummy_module.rst').text()
assert content == ''
assert 'autosummary_dummy_module.rst' in app._warning.getvalue()


@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
confoverrides={'autosummary_generate_option': 'overwrite'})
def test_autosummary_generate_option_overwrite(app_params, make_app):
args, kwargs = app_params
srcdir = kwargs.get('srcdir')

(srcdir / 'generated').makedirs(exist_ok=True)
(srcdir / 'generated' / 'autosummary_dummy_module.rst').write_text('')

app = make_app(*args, **kwargs)
content = (srcdir / 'generated' / 'autosummary_dummy_module.rst').text()
assert content != ''
assert 'autosummary_dummy_module.rst' not in app._warning.getvalue()


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

0 comments on commit 5b50c8a

Please sign in to comment.