Sphinx autodoc不够自动化

Cor*_*ker 139 python python-sphinx

我正在尝试使用Sphinx来记录Python中的5000多行项目.它有大约7个基本模块.据我所知,为了使用autodoc我需要为我的项目中的每个文件编写这样的代码:

.. automodule:: mods.set.tests
    :members:
    :show-inheritance:
Run Code Online (Sandbox Code Playgroud)

这太繁琐了,因为我有很多文件.如果我能指定我想要记录'mods'包,那将会容易得多.然后,Sphinx可以递归地遍历包并为每个子模块创建一个页面.

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

Eti*_*nne 130

您可以查看我制作的脚本.我认为它可以帮到你.

此脚本解析目录树以查找python模块和包,并相应地创建ReST文件以使用Sphinx创建代码文档.它还创建了一个模块索引.

UPDATE

此脚本现在是apidoc的Sphinx 1.1的一部分.

  • 自我回答:将`..include :: modules.rst`添加到你的`index.rst`中 (4认同)
  • 甚至 sphinx-apidoc 也非常初级。对于包含一两个模块的包,它工作正常,但我们的模块嵌套得很深,并且 sphinx-apidoc 会产生一些相当难以管理的输出。 (2认同)

Jam*_*ham 64

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

因此,不再需要硬编码模块名称或依赖第 3 方库(如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
Run Code Online (Sandbox Code Playgroud)

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']
Run Code Online (Sandbox Code Playgroud)

index.rst(注意新:recursive:选项):

Welcome to My Toolbox
=====================

Some words.

.. autosummary::
   :toctree: _autosummary
   :template: custom-module-template.rst
   :recursive:

   mypackage
Run Code Online (Sandbox Code Playgroud)

这足以自动总结包中的每个模块,无论嵌套有多深。对于每个模块,它然后总结该模块中的每个属性、函数、类和异常。

但奇怪的是,默认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.rstindex.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 %}
Run Code Online (Sandbox Code Playgroud)

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 %}
Run Code Online (Sandbox Code Playgroud)

  • 只是对 `custom-module-template.rst` 的一个小改进,如果您在 `.. automodule:: {{ fullname }}` (第 3 行)下添加 `:members:`,则该模块的文档将自动除了目录树之外,还填充了成员(类、函数等)。除了使用目录树精确定位功能之外,用户还可以选择快速浏览文档。 (4认同)
  • 非常感谢你做的这些!!!我几乎要放弃了,然后终于找到了这个。一个问题。我正在使用 `sys.path.insert(0, os.path.abspath('../../mypackage'))` 但你只使用 `'../..'` 。为什么没有区别呢? (2认同)
  • 没问题,很高兴有帮助。狮身人面像几乎让我发疯,直到我弄清楚了;现在一切都很顺利。在“index.rst”中,您需要显式命名要开始“:recursive:”文档字符串提取的包,因此在我的示例中为“mypackage”。在“conf.py”中,您只需提供到该位置的路由。这是因为在我的示例中,“mypackage”是“mytoolbox”中的顶级文件夹,但如果它(例如)嵌套在“source/mypackage”子文件夹中,则“conf.py”将读取“../..” /来源`。 (2认同)
  • 这个答案很金,非常感谢!希望您的功能请求得到实现。这确实应该是默认行为。 (2认同)

fir*_*iku 33

我不知道Sphinx autosummary在询问原始问题的时候是否有扩展,但是现在很有可能在没有使用sphinx-apidoc或类似脚本的情况下设置这种类型的自动生成.下面有一些设置适用于我的一个项目.

  1. 在文件中启用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']
    
    Run Code Online (Sandbox Code Playgroud)
  2. autosummary::index.rst文件中的TOC树中使用.在用于模块此示例中的文档project.module1project.module2将自动生成并放入_autosummary目录.

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

    {{ fullname }}
    {{ underline }}
    
    .. automodule:: {{ fullname }}
        :members:
    
    Run Code Online (Sandbox Code Playgroud)

总之,没有必要将_autosummary目录保持在版本控制之下.此外,您可以将其命名为任何名称,并将其放置在源树中的任何位置(_build尽管如此,将其放在下面也不起作用).

  • 这是一个巨大的帮助.在第2点,你有"project.module1"和"project.module2",有没有办法为给定包中的每个模块自动生成该列表?只是把"项目"并让它嗅出"module1"和"module2"? (4认同)
  • @AlisdairRobertson不,但提供的自动解决方案最终足以满足我的需求.我想做的唯一另一件事是编写一个脚本来生成index.rst文件并自动检测模块名称.但是,实际上,模块列表并没有经常改变,所以只是偶尔编辑一个文件并不是不合理的.我确信我已经花了很多时间寻找解决方案,而不是只编辑那个文件! (2认同)

Vit*_*ito 16

Sphinx AutoAPI正是这样做的。

  • 同上。这会将“auto”放入“autodoc”中......这是我们项目切换时必须要做的所有事情:[由 nealmcb 从 autodoc 切换到 autoapi · Pull Request \#7 · gwexploratoryaudits/r2b2](https://github .com/gwexploratoryaudits/r2b2/pull/7) (4认同)
  • 哦,我的天啊!这比其他任何东西都有效。*请注意,这不是“autodoc”或“apidoc”,它是一个完全不同的扩展。* (3认同)
  • 链接不是答案,请详细说明 (3认同)

S.L*_*ott 11

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

然后你可以.. automodule:: package,它主要做你想要的.

  • @Cory Walker:这不是"一个"字符串.您可以 - 并且**应该** - 在每个文件中放置三重引用的文档字符串.每一个人.这包括包中的`__init __.py`文件.docstring可以包含任何Sphinx文档指令,包括包中模块的`.. automodule ::`. (4认同)
  • `autodoc`是一个错字,它应该是`automodule`.但非常感谢提示! (2认同)
  • 您能否发布一个完整的示例“__init__.py”,在给定模块名称“foo”的情况下准确显示该行应放置的位置? (2认同)