Sphinx autodoc不够自动化


149

我正在尝试使用Sphinx在Python中记录5,000多个项目。它有大约7个基本模块。据我所知,为了使用自动文档,我需要为项目中的每个文件编写如下代码:

.. automodule:: mods.set.tests
    :members:
    :show-inheritance:

这太繁琐了,因为我有很多文件。如果我只想指定要记录的“ mods”包,那会容易得多。然后,Sphinx可以递归地浏览包并为每个子模块创建一个页面。

有这样的功能吗?如果没有,我可以编写一个脚本来制作所有.rst文件,但这将花费很多时间。


编写使用“ os.walk”并编写所有这些脚本的小脚本有什么问题?顺便说一句,我有一个超过40,000的生产线项目,不清楚您在说什么。涉及多少个文件?路由ls到文件并对其进行编辑有多困难?
S.Lott

124
没有人说这很难。OP表示这很乏味。鉴于其他文档系统可以做到这一点,这并非不合理。
Gregg Lind 2010年

只需使用pdoc即可
K3 --- rnc

Answers:


143

您可以检查我编写的脚本。我认为它可以帮助您。

该脚本解析目录树以查找python模块和软件包,并适当地创建ReST文件以使用Sphinx创建代码文档。它还创建一个模块索引。

更新

现在,此脚本作为apidoc是Sphinx 1.1的一部分


您应该将文件输出到哪里?我尝试将它们输出到Sphinx的默认_build文件夹中,但是运行时sphinx-build -b html . ./_build不会将它们拾取。
Cerin

您应将它们放在source directory(。)中。_build目录是将在其中创建HTML文件的目录。检查更多信息:sphinx.pocoo.org/tutorial.html#running-the-build
Etienne

1
@Erienne:很棒的脚本!正是我想要的。希望它为各个类生成标题(常规的狮身人面像外观对类不好。它们在较大的模块中迷路了)
jbenet 2011年

1
甚至sphinx-apidoc都非常初级。对于具有一个或两个模块的软件包,它可以正常工作,但是我们已经将模块嵌套得很深,并且sphinx-apidoc产生了一些难以管理的输出。
slacy 2012年

4
自我回答:添加.. include:: modules.rst到您的index.rst
Ciro Santilli郝海东冠状病六四事件法轮功

39

我不知道autosummary在最初提出问题时Sphinx是否具有扩展名,但是现在很可能无需使用sphinx-apidoc类似脚本就可以设置这种自动生成。下面是适用于我的一个项目的设置。

  1. 在文件中启用autosummary扩展名(以及autodocconf.py,并将其autosummary_generate选项设置为True。如果您不使用自定义*.rst模板,这可能就足够了。否则,请添加您的模板目录以排除列表,或者autosummary尝试将它们视为输入文件(这似乎是一个错误)。

    extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosummary']
    autosummary_generate = True
    templates_path = [ '_templates' ]
    exclude_patterns = ['_build', '_templates']
  2. autosummary::index.rst文件的目录树中使用。在用于模块此示例中的文档project.module1project.module2将自动生成并放入_autosummary目录。

    PROJECT
    =======
    
    .. toctree::
    
    .. autosummary::
       :toctree: _autosummary
    
       project.module1
       project.module2
  3. 默认情况下,autosummary只会为模块及其功能生成非常简短的摘要。要进行更改,可以将自定义模板文件放入_templates/autosummary/module.rst(将使用Jinja2进行解析):

    {{ fullname }}
    {{ underline }}
    
    .. automodule:: {{ fullname }}
        :members:

总之,无需将_autosummary目录保持在版本控制之下。另外,您可以_build随意命名它,并将其放在源代码树中的任何位置(不过,将其放在下面将不起作用)。


4
这是一个巨大的帮助。在第2点中,您拥有“ project.module1”和“ project.module2”,有没有办法自动为给定包中的每个模块生成该列表?仅放置“项目”并嗅出“ module1”和“ module2”?
布朗

很惊讶我在任何地方都找不到答案,你有没有解决过@Brown?
Alisdair Robertson

3
@AlisdairRobertson不,但是最终提供的自动摘要解决方案足以满足我的需求。我唯一想做的另一件事是编写一个脚本来生成index.rst文件并自动检测模块名称。但是,实际上,模块列表不会经常更改,因此,偶尔编辑一个文件并不是没有道理的。我敢肯定,与仅编辑一个文件相比,寻找解决方案所花费的时间要多得多!
布朗

12

在每个包中,__init__.py文件可以具有.. automodule:: package.module包中每个部分的组件。

然后,您可以.. automodule:: package并且它基本上可以完成您想要的。


我只是将该字符串放在init .py 中的三引号中吗?
科里·沃克

5
@Cory Walker:不是“ a”字符串。您可以而且应该 -在每个文件中放入三引号的文档字符串。每一个 这包括__init__.py您包中的文件。该文档字符串可以包含ANY Sphinx文档指令,包括.. automodule::该软件包中模块的指令。
S.Lott

2
autodoc是错字,应该是automodule。但是非常感谢您的提示!
mariotomo 2011年

9

从Sphinx 3.1版(2020年6月)开始,sphinx.ext.autosummary(最终!)具有递归功能。

因此,不再需要对模块名称进行硬编码,也无需依赖Sphinx AutoAPISphinx 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.rstmytoolbox/doc/source/_templates/custom-module-template.rst
  • 复制site-packages/sphinx/ext/autosummary/templates/autosummary/class.rstmytoolbox/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 %}


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.