mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
autosummary: Add :recursive: option to autosummary directive
This commit is contained in:
parent
665458561f
commit
476b73b6ca
@ -104,6 +104,20 @@ The :mod:`sphinx.ext.autosummary` extension does this in three parts:
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
* You can specify the ``recursive`` option to generate documents for
|
||||
modules and sub-packages recursively. It defaults to disabled.
|
||||
For example, ::
|
||||
|
||||
.. autosummary::
|
||||
:recursive:
|
||||
|
||||
sphinx.environment.BuildEnvironment
|
||||
|
||||
It is needed to enable :confval:`autosummary_recursive` also to
|
||||
use this option.
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
|
||||
:program:`sphinx-autogen` -- generate autodoc stub pages
|
||||
--------------------------------------------------------
|
||||
|
@ -224,6 +224,7 @@ class Autosummary(SphinxDirective):
|
||||
option_spec = {
|
||||
'toctree': directives.unchanged,
|
||||
'nosignatures': directives.flag,
|
||||
'recursive': directives.flag,
|
||||
'template': directives.unchanged,
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,8 @@ class DummyApplication:
|
||||
|
||||
AutosummaryEntry = NamedTuple('AutosummaryEntry', [('name', str),
|
||||
('path', str),
|
||||
('template', str)])
|
||||
('template', str),
|
||||
('recursive', bool)])
|
||||
|
||||
|
||||
def setup_documenters(app: Any) -> None:
|
||||
@ -266,8 +267,13 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
|
||||
_warn('[autosummary] failed to import %r: %s' % (name, e))
|
||||
continue
|
||||
|
||||
if entry.recursive and not recursive:
|
||||
_warn('[autosummary] :resursive: option found. But ignored. '
|
||||
'Please read document for autosummary_recursive option')
|
||||
|
||||
content = generate_autosummary_content(name, obj, parent, template, entry.template,
|
||||
imported_members, app, recursive)
|
||||
imported_members, app,
|
||||
recursive and entry.recursive)
|
||||
|
||||
filename = os.path.join(path, name + suffix)
|
||||
if os.path.isfile(filename):
|
||||
@ -347,11 +353,13 @@ def find_autosummary_in_lines(lines: List[str], module: Any = None, filename: st
|
||||
module_re = re.compile(
|
||||
r'^\s*\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
|
||||
autosummary_item_re = re.compile(r'^\s+(~?[_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?')
|
||||
recursive_arg_re = re.compile(r'^\s+:recursive:\s*$')
|
||||
toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
|
||||
template_arg_re = re.compile(r'^\s+:template:\s*(.*?)\s*$')
|
||||
|
||||
documented = [] # type: List[AutosummaryEntry]
|
||||
|
||||
recursive = False
|
||||
toctree = None # type: str
|
||||
template = None
|
||||
current_module = module
|
||||
@ -360,6 +368,11 @@ def find_autosummary_in_lines(lines: List[str], module: Any = None, filename: st
|
||||
|
||||
for line in lines:
|
||||
if in_autosummary:
|
||||
m = recursive_arg_re.match(line)
|
||||
if m:
|
||||
recursive = True
|
||||
continue
|
||||
|
||||
m = toctree_arg_re.match(line)
|
||||
if m:
|
||||
toctree = m.group(1)
|
||||
@ -384,7 +397,7 @@ def find_autosummary_in_lines(lines: List[str], module: Any = None, filename: st
|
||||
if current_module and \
|
||||
not name.startswith(current_module + '.'):
|
||||
name = "%s.%s" % (current_module, name)
|
||||
documented.append(AutosummaryEntry(name, toctree, template))
|
||||
documented.append(AutosummaryEntry(name, toctree, template, recursive))
|
||||
continue
|
||||
|
||||
if not line.strip() or line.startswith(base_indent + " "):
|
||||
@ -396,6 +409,7 @@ def find_autosummary_in_lines(lines: List[str], module: Any = None, filename: st
|
||||
if m:
|
||||
in_autosummary = True
|
||||
base_indent = m.group(1)
|
||||
recursive = False
|
||||
toctree = None
|
||||
template = None
|
||||
continue
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
.. autosummary::
|
||||
:toctree: modules
|
||||
:recursive:
|
||||
{% for item in modules %}
|
||||
{{ item }}
|
||||
{%- endfor %}
|
||||
|
@ -5,5 +5,11 @@ API Reference
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated
|
||||
:recursive:
|
||||
|
||||
package
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated
|
||||
|
||||
package2
|
||||
|
@ -0,0 +1,13 @@
|
||||
from os import * # NOQA
|
||||
|
||||
|
||||
class Foo:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def bar(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def baz(self):
|
||||
pass
|
@ -292,6 +292,11 @@ def test_autosummary_recursive_enabled(app, status, warning):
|
||||
if toctree:
|
||||
assert not (generated / toctree).exists()
|
||||
|
||||
# autosummary without :recursive: option
|
||||
generated = app.srcdir / 'generated'
|
||||
assert (generated / 'package2.rst').exists()
|
||||
assert not (generated / 'package2.module.rst').exists()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('dummy', testroot='ext-autosummary-recursive',
|
||||
srcdir='ext-autosummary-recursive-disabled',
|
||||
@ -382,7 +387,7 @@ def test_autosummary_imported_members(app, status, warning):
|
||||
@pytest.mark.sphinx(testroot='ext-autodoc')
|
||||
def test_generate_autosummary_docs_property(app):
|
||||
with patch('sphinx.ext.autosummary.generate.find_autosummary_in_files') as mock:
|
||||
mock.return_value = [AutosummaryEntry('target.methods.Base.prop', 'prop', None)]
|
||||
mock.return_value = [AutosummaryEntry('target.methods.Base.prop', 'prop', None, False)]
|
||||
generate_autosummary_docs([], output_dir=app.srcdir, builder=app.builder, app=app)
|
||||
|
||||
content = (app.srcdir / 'target.methods.Base.prop.rst').text()
|
||||
|
Loading…
Reference in New Issue
Block a user