Использование Jinja2 с автосводкой Sphinx

Я пытаюсь использовать 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"]
}

Методы rstjinja() а также setup()были заимствованы отсюда. В нем четко указано, что:

Шаблоны Jinja будут обработаны до обработки RST.

Мой.rst файл выглядит следующим образом:

#####
Title
#####

.. currentmodule:: Package.SubModule

.. autosummary::
    :nosignatures:
    :toctree:

    {% for item in entities %}
        {{ item }}
    {% endfor %}

Вывод правильно показывает мне сводную таблицу, состоящую из 3 записей (по одной для каждого из трех указанных мною классов: "classA", "classB", "classD"). В первом столбце отображается имя класса, а во втором столбце - однострочное описание (из его строки документации). Данные во втором столбце четко указывают на то, что Sphinx может идентифицировать соответствующие классы и извлекать их строки документации.

Моя проблема в том, что "автосуммари" не генерирует заглушки для этих классов, и поэтому эти записи в таблице нельзя щелкнуть. На терминале я вижу следующее предупреждение для каждого из классов с отсутствующими заглушками:

ВНИМАНИЕ: autosummary: не найден файл-заглушка Package.SubModule.classA. Проверьте настройку autosummary_generate.

Как видно из моего файла conf.py, этот параметр уже True.

Если я изменю (ради изучения) файл.rst на следующее:

#####
Title
#####

.. currentmodule:: Package.SubModule

.. autosummary::
    :nosignatures:
    :toctree:

    {% for item in entities %}
        {{ item }}
    {% endfor %}
    classA

Затем я получаю таблицу, аналогичную предыдущему случаю, но с дополнительной строкой в ​​конце, соответствующей "classA". И что интересно, обе записи для "classA" (первая сгенерирована с помощью Jinja, вторая - с помощью явного указания) теперь являются гиперссылкой на заглушку, созданную для "classA".

Почему это так? Почему не создаются заглушки, если одна и та же информация указывается только через Jinja (хотя sphinx действительно отображает строки документации для них в таблице)?

Как я могу решить эту проблему? Для меня важно иметь возможность предоставить список сущностей, которые нужно документировать через Jinja (поскольку я определяю их с помощью некоторого кода Python вconf.py).

Дополнительная информация: в приведенном выше примере классы можно импортировать через

from Package.SubModule import classA, classB, classD

1 ответ

Решение

Я нашел обходной путь, используя расширение 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
}

ПРИМЕЧАНИЕ: список классов, переданных через 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
}

Пример моего.rst файла:

##########
Submodules
##########

.. automodapi:: package_name.submodule_name
    :nosignatures:
    :no-main-docstr:
    :skip: {{ entities|join(', ') }}
Другие вопросы по тегам