Автодок Сфинкса не достаточно автоматический

Я пытаюсь использовать Sphinx для документирования проекта на 5000 строк в Python. Имеет около 7 базовых модулей. Насколько я знаю, чтобы использовать autodoc, мне нужно написать такой код для каждого файла в моем проекте:

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

Это слишком утомительно, потому что у меня много файлов. Было бы намного проще, если бы я мог просто указать, что я хочу, чтобы пакет 'mods' был задокументирован. Затем Sphinx может рекурсивно пройтись по пакету и создать страницу для каждого подмодуля.

Есть ли такая функция? Если бы не я, я мог бы написать скрипт для создания всех файлов.rst, но это заняло бы много времени.

4 ответа

Решение

Вы можете проверить этот скрипт, который я сделал. Я думаю, что это может помочь вам.

Этот скрипт анализирует дерево каталогов в поисках модулей и пакетов python и создает файлы ReST соответствующим образом для создания документации кода с помощью Sphinx. Это также создает индекс модулей.

ОБНОВИТЬ

Этот скрипт теперь является частью Sphinx 1.1 как apidoc.

Начиная с версии 3.1 Sphinx (июнь 2020 г.), 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 или похожий сценарий. Ниже приведены настройки, которые работают для одного из моих проектов.

  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']
    
  2. использование autosummary:: в оглавлении дерево в вашем index.rst файл. В этом примере документация для модулей project.module1 а также project.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 не будет работать, хотя).

Sphinx AutoAPI делает именно это.

В каждой упаковке __init__.py файл может иметь .. automodule:: package.module компоненты для каждой части пакета.

Тогда ты можешь .. automodule:: package и это в основном делает то, что вы хотите.

Может быть, то, что вы ищете, это Epydoc и это расширение Sphinx.

Другие вопросы по тегам