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

149

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

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

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

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

Кори Уокер
источник
Что не так с написанием небольшого скрипта, который использует "os.walk" и пишет все это? Кстати, у меня есть более 40 000 линейных проектов, и мне неясно, о чем вы говорите. Сколько файлов задействовано? Насколько сложно может быть маршрут lsк файлу и редактировать это?
С.Лотт
125
Никто не сказал, что это было сложно. ОП сказал, что это утомительно , и это так. Учитывая, что другие системы документации могут сделать это, это не лишено смысла.
Грегг Линд
Просто используйте pdoc .
K3 --- rnc

Ответы:

143

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

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

ОБНОВИТЬ

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

Etienne
источник
Куда вы должны выводить файлы? Я попытался вывести их в папку _build Sphinx по умолчанию, но при запуске sphinx-build -b html . ./_buildне подхватил их.
Cerin
Вы должны положить их в source directory(. В вашем случае). Каталог _build - это место, где будут создаваться файлы HTML. Проверьте для получения дополнительной информации: sphinx.pocoo.org/tutorial.html#running-the-build
Этьен
1
@Erienne: фантастический сценарий! именно то, что я искал. Желаю, чтобы он генерировал заголовки для отдельных классов (обычный вид сфинкса не подходит для классов. Они теряются в больших модулях)
jbenet
1
Даже сфинкс-апидок довольно рудиментарен. Для пакета с одним или двумя модулями это работает нормально, но у нас есть глубоко вложенные модули, и sphinx-apidoc выдает довольно неуправляемый вывод.
рабство
4
автоответчик: добавьте .. include:: modules.rstв свойindex.rst
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
40

Я не знаю, имел ли Сфинкс 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::в дереве TOC в вашем 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не будет работать).

firegurafiku
источник
4
Это была огромная помощь. В пункте 2, где у вас есть "project.module1" и "project.module2", есть ли способ автоматически сгенерировать этот список для каждого модуля в данном пакете? Просто поставить «проект» и понюхать «модуль1» и «модуль2»?
Браун
Очень удивлен, что нигде не могу найти ответ на этот вопрос, ты когда-нибудь решал это @Brown?
Алисдаир Робертсон
3
@AlisdairRobertson Нет, но предоставленное автоматическое решение оказалось более чем адекватным для моих нужд. Единственное, что я хотел сделать, - написать скрипт для генерации файла index.rst и автоматического определения имен модулей. Однако на практике список модулей меняется не так часто, так что просто редактировать один файл время от времени не так уж неразумно. Я уверен, что уже потратил гораздо больше времени на поиск решения, чем просто редактирование этого файла!
Браун
12

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

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

С. Лотт
источник
мне просто поместить эту строку в тройные кавычки в init .py?
Кори Уокер
5
@ Кори Уокер: Это не строка "а". Вы можете - и должны - помещать строки документов с тройными кавычками в каждый отдельный файл. Все. Это включает в себя __init__.pyфайлы в ваших пакетах. Строка документации может содержать ЛЮБЫЕ директивы документации Sphinx, в том числе .. automodule::для модулей в пакете.
S.Lott
2
autodocэто опечатка, так и должно быть automodule. но большое спасибо за подсказку!
Мариотомо
9

С версии Sphinx 3.1 (июнь 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 %}
Джеймс Лидхэм
источник
7

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

Vito
источник
1
Боже мой! Это работает намного лучше, чем все остальное. Обратите внимание, что это не «autodoc» или «apidoc», это совершенно другое расширение.
веревочный пузырь
2
То же самое. Это помещает «auto» в «autodoc» .... Вот все, что наш проект должен был сделать, чтобы переключиться: переключиться на autoapi из autodoc с помощью nealmcb · Запрос на извлечение \ # 7 · gwexploratoryaudits / r2b2
nealmcb