mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
revisions per comments from tk0miya
This commit is contained in:
parent
f9e9bdc4a0
commit
de4aca857c
@ -288,6 +288,10 @@ The following variables available in the templates:
|
|||||||
List containing names of "public" attributes in the class/module. Only
|
List containing names of "public" attributes in the class/module. Only
|
||||||
available for classes and modules.
|
available for classes and modules.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.1
|
||||||
|
|
||||||
|
Attributes of modules are supported.
|
||||||
|
|
||||||
.. data:: modules
|
.. data:: modules
|
||||||
|
|
||||||
List containing names of "public" modules in the package. Only available for
|
List containing names of "public" modules in the package. Only available for
|
||||||
|
@ -42,6 +42,7 @@ from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warnin
|
|||||||
from sphinx.ext.autodoc import Documenter
|
from sphinx.ext.autodoc import Documenter
|
||||||
from sphinx.ext.autosummary import import_by_name, get_documenter
|
from sphinx.ext.autosummary import import_by_name, get_documenter
|
||||||
from sphinx.locale import __
|
from sphinx.locale import __
|
||||||
|
from sphinx.pycode import ModuleAnalyzer, PycodeError
|
||||||
from sphinx.registry import SphinxComponentRegistry
|
from sphinx.registry import SphinxComponentRegistry
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util import rst
|
from sphinx.util import rst
|
||||||
@ -218,6 +219,21 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
|
|||||||
public.append(name)
|
public.append(name)
|
||||||
return public, items
|
return public, items
|
||||||
|
|
||||||
|
def get_module_attrs(members: Any) -> Tuple[List[str], List[str]]:
|
||||||
|
"""Find module attributes with docstrings."""
|
||||||
|
attrs, public = [], []
|
||||||
|
try:
|
||||||
|
analyzer = ModuleAnalyzer.for_module(name)
|
||||||
|
attr_docs = analyzer.find_attr_docs()
|
||||||
|
for namespace, attr_name in attr_docs:
|
||||||
|
if namespace == '' and attr_name in members:
|
||||||
|
attrs.append(attr_name)
|
||||||
|
if not attr_name.startswith('_'):
|
||||||
|
public.append(attr_name)
|
||||||
|
except PycodeError:
|
||||||
|
pass # give up if ModuleAnalyzer fails to parse code
|
||||||
|
return attrs, public
|
||||||
|
|
||||||
def get_modules(obj: Any) -> Tuple[List[str], List[str]]:
|
def get_modules(obj: Any) -> Tuple[List[str], List[str]]:
|
||||||
items = [] # type: List[str]
|
items = [] # type: List[str]
|
||||||
for _, modname, ispkg in pkgutil.iter_modules(obj.__path__):
|
for _, modname, ispkg in pkgutil.iter_modules(obj.__path__):
|
||||||
@ -237,24 +253,11 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
|
|||||||
get_members(obj, {'class'}, imported=imported_members)
|
get_members(obj, {'class'}, imported=imported_members)
|
||||||
ns['exceptions'], ns['all_exceptions'] = \
|
ns['exceptions'], ns['all_exceptions'] = \
|
||||||
get_members(obj, {'exception'}, imported=imported_members)
|
get_members(obj, {'exception'}, imported=imported_members)
|
||||||
|
ns['attributes'], ns['all_attributes'] = \
|
||||||
|
get_module_attrs(ns['members'])
|
||||||
ispackage = hasattr(obj, '__path__')
|
ispackage = hasattr(obj, '__path__')
|
||||||
if ispackage and recursive:
|
if ispackage and recursive:
|
||||||
ns['modules'], ns['all_modules'] = get_modules(obj)
|
ns['modules'], ns['all_modules'] = get_modules(obj)
|
||||||
|
|
||||||
# Find module attributes with docstrings
|
|
||||||
attrs, public = [], []
|
|
||||||
from sphinx.pycode import ModuleAnalyzer, PycodeError
|
|
||||||
try:
|
|
||||||
analyzer = ModuleAnalyzer.for_module(name)
|
|
||||||
attr_docs = analyzer.find_attr_docs()
|
|
||||||
for _, attr_name in attr_docs:
|
|
||||||
if attr_name in ns['members']:
|
|
||||||
attrs.append(attr_name)
|
|
||||||
if not attr_name.startswith('_'):
|
|
||||||
public.append(attr_name)
|
|
||||||
except PycodeError as err:
|
|
||||||
pass
|
|
||||||
ns['attributes'], ns['all_attributes'] = attrs, public
|
|
||||||
elif doc.objtype == 'class':
|
elif doc.objtype == 'class':
|
||||||
ns['members'] = dir(obj)
|
ns['members'] = dir(obj)
|
||||||
ns['inherited_members'] = \
|
ns['inherited_members'] = \
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
.. autosummary::
|
.. autosummary::
|
||||||
{% for item in attributes %}
|
{% for item in attributes %}
|
||||||
{{item}}
|
{{ item }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -19,3 +19,7 @@ class Foo:
|
|||||||
|
|
||||||
def bar(x: Union[int, str], y: int = 1):
|
def bar(x: Union[int, str], y: int = 1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#: a module-level attribute
|
||||||
|
qux = 2
|
||||||
|
@ -11,4 +11,5 @@
|
|||||||
autosummary_dummy_module.Foo
|
autosummary_dummy_module.Foo
|
||||||
autosummary_dummy_module.Foo.Bar
|
autosummary_dummy_module.Foo.Bar
|
||||||
autosummary_dummy_module.bar
|
autosummary_dummy_module.bar
|
||||||
|
autosummary_dummy_module.qux
|
||||||
autosummary_importfail
|
autosummary_importfail
|
||||||
|
@ -203,16 +203,18 @@ def test_autosummary_generate(app, status, warning):
|
|||||||
[autosummary_table, nodes.table, nodes.tgroup, (nodes.colspec,
|
[autosummary_table, nodes.table, nodes.tgroup, (nodes.colspec,
|
||||||
nodes.colspec,
|
nodes.colspec,
|
||||||
[nodes.tbody, (nodes.row,
|
[nodes.tbody, (nodes.row,
|
||||||
|
nodes.row,
|
||||||
nodes.row,
|
nodes.row,
|
||||||
nodes.row,
|
nodes.row,
|
||||||
nodes.row)])])
|
nodes.row)])])
|
||||||
assert_node(doctree[4][0], addnodes.toctree, caption="An autosummary")
|
assert_node(doctree[4][0], addnodes.toctree, caption="An autosummary")
|
||||||
|
|
||||||
assert len(doctree[3][0][0][2]) == 4
|
assert len(doctree[3][0][0][2]) == 5
|
||||||
assert doctree[3][0][0][2][0].astext() == 'autosummary_dummy_module\n\n'
|
assert doctree[3][0][0][2][0].astext() == 'autosummary_dummy_module\n\n'
|
||||||
assert doctree[3][0][0][2][1].astext() == 'autosummary_dummy_module.Foo()\n\n'
|
assert doctree[3][0][0][2][1].astext() == 'autosummary_dummy_module.Foo()\n\n'
|
||||||
assert doctree[3][0][0][2][2].astext() == 'autosummary_dummy_module.Foo.Bar\n\n'
|
assert doctree[3][0][0][2][2].astext() == 'autosummary_dummy_module.Foo.Bar\n\n'
|
||||||
assert doctree[3][0][0][2][3].astext() == 'autosummary_dummy_module.bar(x[, y])\n\n'
|
assert doctree[3][0][0][2][3].astext() == 'autosummary_dummy_module.bar(x[, y])\n\n'
|
||||||
|
assert doctree[3][0][0][2][4].astext() == 'autosummary_dummy_module.qux\n\na module-level attribute'
|
||||||
|
|
||||||
module = (app.srcdir / 'generated' / 'autosummary_dummy_module.rst').read_text()
|
module = (app.srcdir / 'generated' / 'autosummary_dummy_module.rst').read_text()
|
||||||
assert (' .. autosummary::\n'
|
assert (' .. autosummary::\n'
|
||||||
@ -237,6 +239,11 @@ def test_autosummary_generate(app, status, warning):
|
|||||||
'\n'
|
'\n'
|
||||||
'.. autoclass:: Foo.Bar\n' in FooBar)
|
'.. autoclass:: Foo.Bar\n' in FooBar)
|
||||||
|
|
||||||
|
qux = (app.srcdir / 'generated' / 'autosummary_dummy_module.qux.rst').read_text()
|
||||||
|
assert ('.. currentmodule:: autosummary_dummy_module\n'
|
||||||
|
'\n'
|
||||||
|
'.. autodata:: qux' in qux)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
|
@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
|
||||||
confoverrides={'autosummary_generate_overwrite': False})
|
confoverrides={'autosummary_generate_overwrite': False})
|
||||||
|
Loading…
Reference in New Issue
Block a user