我正在尝试使用 Sphinx 用 Python 记录一个 5,000 多行的项目。它有大约 7 个基本模块。据我所知,为了使用 autodoc,我需要为项目中的每个文件编写这样的代码:
.. automodule:: mods.set.tests
:members:
:show-inheritance:
这太乏味了,因为我有很多文件。如果我可以指定我想要记录“mods”包,那就容易多了。然后,Sphinx 可以递归地遍历包并为每个子模块创建一个页面。
有这样的功能吗?如果没有,我可以编写一个脚本来制作所有 .rst 文件,但这会占用很多时间。
从 Sphinx 3.1 版本(2020 年 6 月)开始,
sphinx.ext.autosummary
(终于!)具有自动递归功能。
因此无需再对模块名称进行硬编码或依赖第三方库(如 Sphinx AutoAPI 或 Sphinx AutoPackageSummary)进行自动包检测。
要记录的 Python 3.7 包示例(请参阅 Github 上的代码 和 ReadTheDocs 上的结果):
mytoolbox
|-- mypackage
| |-- __init__.py
| |-- foo.py
| |-- mysubpackage
| |-- __init__.py
| |-- bar.py
|-- doc
| |-- source
| |--index.rst
| |--conf.py
| |-- _templates
| |-- custom-module-template.rst
| |-- custom-class-template.rst
conf.py
:
import os
import sys
sys.path.insert(0, os.path.abspath('../..')) # Source code dir relative to this file
extensions = [
'sphinx.ext.autodoc', # Core library for html generation from docstrings
'sphinx.ext.autosummary', # Create neat summary tables
]
autosummary_generate = True # Turn on sphinx.ext.autosummary
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
index.rst
(注意新的 :recursive:
选项):
Welcome to My Toolbox
=====================
Some words.
.. autosummary::
:toctree: _autosummary
:template: custom-module-template.rst
:recursive:
mypackage
这足以自动总结包中的每个模块,无论嵌套有多深。对于每个模块,它会总结该模块中的每个属性、函数、类和异常。
但奇怪的是,默认的
sphinx.ext.autosummary
模板不会继续为每个属性、函数、类和异常生成单独的文档页面,也不会从汇总表链接到它们。可以扩展模板来执行此操作,如下所示,但我不明白为什么这不是默认行为 - 这肯定是大多数人想要的......? 我已将其作为功能请求提出。
我必须在本地复制默认模板,然后添加到其中:
site-packages/sphinx/ext/autosummary/templates/autosummary/module.rst
到mytoolbox/doc/source/_templates/custom-module-template.rst
site-packages/sphinx/ext/autosummary/templates/autosummary/class.rst
到mytoolbox/doc/source/_templates/custom-class-template.rst
使用
custom-module-template.rst
选项,挂钩到 index.rst
位于上面的 :template:
中。 (删除该行以查看使用默认站点包模板会发生什么。)
custom-module-template.rst
(右侧标注的附加行):
{{ fullname | escape | underline}}
.. automodule:: {{ fullname }}
{% block attributes %}
{% if attributes %}
.. rubric:: Module Attributes
.. autosummary::
:toctree: <-- add this line
{% for item in attributes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block functions %}
{% if functions %}
.. rubric:: {{ _('Functions') }}
.. autosummary::
:toctree: <-- add this line
{% for item in functions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block classes %}
{% if classes %}
.. rubric:: {{ _('Classes') }}
.. autosummary::
:toctree: <-- add this line
:template: custom-class-template.rst <-- add this line
{% for item in classes %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block exceptions %}
{% if exceptions %}
.. rubric:: {{ _('Exceptions') }}
.. autosummary::
:toctree: <-- add this line
{% for item in exceptions %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block modules %}
{% if modules %}
.. rubric:: Modules
.. autosummary::
:toctree:
:template: custom-module-template.rst <-- add this line
:recursive:
{% for item in modules %}
{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
custom-class-template.rst
(右侧标注的附加行):
{{ fullname | escape | underline}}
.. currentmodule:: {{ module }}
.. autoclass:: {{ objname }}
:members: <-- add at least this line
:show-inheritance: <-- plus I want to show inheritance...
:inherited-members: <-- ...and inherited members too
{% block methods %}
.. automethod:: __init__
{% if methods %}
.. rubric:: {{ _('Methods') }}
.. autosummary::
{% for item in methods %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block attributes %}
{% if attributes %}
.. rubric:: {{ _('Attributes') }}
.. autosummary::
{% for item in attributes %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
autosummary
扩展,但现在很有可能在不使用sphinx-apidoc
或类似脚本的情况下设置这种类型的自动生成。下面是适用于我的项目之一的设置。
在
autosummary
文件中启用 autodoc
扩展(以及 conf.py
)并将其 autosummary_generate
选项设置为 True
。如果您不使用自定义 *.rst
模板,这可能就足够了。否则将模板目录添加到排除列表,或者 autosummary
会尝试将它们视为输入文件(这似乎是一个错误)。
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary']
autosummary_generate = True
templates_path = [ '_templates' ]
exclude_patterns = ['_build', '_templates']
在
autosummary::
文件的目录树中使用 index.rst
。在此示例中,模块 project.module1
和 project.module2
的文档将自动生成并放入 _autosummary
目录中。
PROJECT
=======
.. toctree::
.. autosummary::
:toctree: _autosummary
project.module1
project.module2
默认情况下,
autosummary
只会生成模块及其功能的非常简短的摘要。要更改它,您可以将自定义模板文件放入 _templates/autosummary/module.rst
(将使用 Jinja2 进行解析):
{{ fullname }}
{{ underline }}
.. automodule:: {{ fullname }}
:members:
总之,无需将
_autosummary
目录置于版本控制之下。另外,您可以将其命名为任何您想要的名称,并将其放置在源代码树中的任何位置(但将其放在 _build
下面是行不通的)。
Sphinx AutoAPI 正是这样做的。
在每个包中,
__init__.py
文件可以包含包的每个部分的 .. automodule:: package.module
组件。
然后你就可以
.. automodule:: package
,它基本上可以满足你的需求。
我找到的解决方案如下:将所有模块添加到您的
__init__.py
文件中。当 Sphinx autodoc 处理您的模块时,它会查找 all 属性来确定生成的文档中应包含哪些名称。
项目树
project
├── src
| ├── __init__.py
| ├── bar.py
├── __init__.py
├── foo.py
在project/src/内
__init__.py
看起来像这样:
from project/subpackage import foo
__all__ = ["foo"]
在项目内部
__init__.py
看起来像这样:
from project/subpackage import bar
__all__ = ["bar"]