Sha*_*tan 5 jinja2 python-3.x python-sphinx autodoc toctree
我正在尝试使用sphinx.ext.autosummary来记录 Python 包。由于“自动摘要”要求我们列出要包含的所有项目,因此我想使用 Jinja2 来指定这些项目。
我的conf.py如下(显示相关部分):
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
autodoc_default_options = {
'imported-members':True
}
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
# in actual usage, `entities` is determined at docs generation time via some code
html_context = {
'entities' : ["classA", "classB", "classD"]
}
Run Code Online (Sandbox Code Playgroud)
方法rstjinja()和方法setup()都是从这里借来的。它明确指出:
Jinja 模板将在处理 RST 之前渲染。
我的 .rst 文件如下:
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
输出正确地显示了一个由 3 个条目组成的汇总表(一个对应我指定的三个类中的每一个:“classA”、“classB”、“classD”)。第一列显示类的名称,第二列显示单行描述(来自其文档字符串)。第二列中的数据清楚地表明 Sphinx 能够识别相关类并提取其文档字符串。
我的问题是“自动摘要”不会为这些类生成存根,因此表中的这些条目不可单击。在终端上,我看到每个缺少存根的类都出现以下警告:
警告:自动摘要:未找到存根文件“Package.SubModule.classA”。检查您的 autosummary_generate 设置。
正如我的 conf.py 文件中所见,此设置已经是True.
如果我将 .rst 文件更改为以下内容(为了探索):
#####
Title
#####
.. currentmodule:: Package.SubModule
.. autosummary::
:nosignatures:
:toctree:
{% for item in entities %}
{{ item }}
{% endfor %}
classA
Run Code Online (Sandbox Code Playgroud)
然后我得到一个与前一个情况类似的表,但在末尾有一个额外的行对应于“classA”。有趣的是,“classA”的两个条目(第一个通过 Jinja 生成,第二个通过显式指定)现在超链接到为“classA”创建的存根。
为什么会这样呢?当仅通过 Jinja 指定相同信息时,为什么不创建存根(即使 sphinx 确实在表中显示了这些信息的文档字符串)?
我该如何解决这个问题?对我来说,能够提供要通过 Jinja 记录的实体列表非常重要(因为我通过 中的一些 Python 代码确定了这些实体conf.py)。
附加信息:在上面的示例中,可以通过以下方式导入类
from Package.SubModule import classA, classB, classD
我找到了使用sphinx_automodapi.automodapi扩展的解决方法。
我的相关内容conf.py:
import sphinx_automodapi
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
'sphinx_automodapi.automodapi'
]
add_module_names = False
autosummary_generate = True
numpydoc_show_class_members = False
def rstjinja(app, docname, source):
"""
Render our pages as a jinja template for fancy templating goodness.
"""
# Make sure we're outputting HTML
if app.builder.format != 'html':
return
src = source[0]
rendered = app.builder.templates.render_string(
src, app.config.html_context
)
source[0] = rendered
def setup(app):
app.connect("source-read", rstjinja)
html_context = {
'entities' : ["classC", "classE"] # NOTE: specify classes NOT to be included/documented; items specified here will be skipped in doc generation
}
Run Code Online (Sandbox Code Playgroud)
注意:通过的类列表html_context是要从文档中排除的类。如果扩展允许直接指定所需的类,那就太好了。我已经开了一张票(此处: https: //github.com/astropy/sphinx-automodapi/issues/92)(目前尚未解决)。
在实际使用中,类列表可以动态确定。例如:
import inspect, importlib, sciunit
package_import_name = "package_name"
submodule = "{}.submodule_name".format(package_import_name)
module = importlib.import_module(submodule)
exlcude_classes = [x[0] for x in inspect.getmembers(module,
lambda member: inspect.isclass(member)
and not(<<specify condition>>))]
html_context = {
'entities' : exlcude_classes
}
Run Code Online (Sandbox Code Playgroud)
我的 .rst 文件示例:
##########
Submodules
##########
.. automodapi:: package_name.submodule_name
:nosignatures:
:no-main-docstr:
:skip: {{ entities|join(', ') }}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2109 次 |
| 最近记录: |