Как napoleon и autodoc взаимодействуют, документируя участников

Я заметил изменения в том, как Sphinx отображает описания классов. Учитывая этот код

# my example happens to be a dataclass, but the behavior for 
# regular classes is the same
@dataclass
class TestClass:
    """This is a test class for dataclasses.

    This is the body of the docstring description.
    """
    var_int: int
    var_str: str

плюс некоторые общие настройки Sphinx, я использовал это около двух лет назад

Документация показывает только строку документации

И теперь я получаю это

Документация показывает переменные класса, как если бы они были в строке документации

Есть ли способ сказать Sphinx не добавлять переменные класса в конец определения класса? Особенно раздражает то, что он предполагает, что их значения равны None, только потому, что у них нет значений по умолчанию.


Эта проблема возникла во время обсуждений в этой публикации, которая также содержит немного больше контекста в комментариях относительно конфигурации Sphinx и т. д.


person Arne    schedule 29.10.2020    source источник
comment
Я не могу воспроизвести это с помощью Sphinx 3.2.1 и Python 3.8.5.   -  person mzjn    schedule 29.10.2020
comment
Когда вы говорите: Есть ли способ указать Sphinx не добавлять переменные класса в конец определения класса? вы имеете в виду не добавлять их вообще или включать да, но только не в самом конце? низ? Кроме того, каким было бы желаемое поведение в отношении значения None? Опустить его вместе со знаком равенства?   -  person bad_coder    schedule 29.10.2020
comment
@bad_coder Я имею в виду вообще не добавлять их, и поведение None для меня просто странно. У них нет значения None, иначе они были бы неопределенными. Но, строго говоря, это другой вопрос.   -  person Arne    schedule 29.10.2020
comment
@mzjn Здесь работает один: суть. Я попробовал то, что вы предложили @bad_coder относительно :undoc-members:, и это решает мою проблему. Честно говоря, я так и не удосужился выяснить, что означают директивы в autodoc-generated first. Возможно, значение по умолчанию для autodoc_default_options в undoc-members раньше было false, а теперь true, но мне лень искать эту информацию. Не стесняйтесь публиковать conf.py, который меняет его обратно на false в качестве ответа, который я могу принять =)   -  person Arne    schedule 29.10.2020


Ответы (1)


Члены объекта включаются директивой autodoc в зависимости от того, если:

  • используется опция :members: (для участников со строками документации).
  • используется опция :undoc-members: (для участников без строк документации).

Например:

dc module
=========

.. autoclass:: dc.Foo

В приведенном выше файле .rst в директиве autodoc не заданы явные параметры, Sphinx будет неявно применять флаги параметров, взятые из autodoc_default_flags в conf.py.

Установка следующего в conf.py приведет к тому, что все элементы объекта (со строками документации или без них) будут включены Sphinx во все директивы, которые явно не указывают параметры.

# autodoc settings
autodoc_default_options = {
    'members':          True,
    'undoc-members':    True,
}

Результат:

введите здесь описание изображения

Однако возникает вопрос: что делают расширения autodoc и sphinx-napoleon, если члены явно указаны в Attributes раздел строки документации но также включен в расширение autodoc?

Строки документации

Napoleon интерпретирует каждую строку документации, которую может найти autodoc (... ) Внутри каждой строки документации специально отформатированные разделы анализируются и преобразуются в reStructuredText.

Например, используя следующую строку документации вместе с параметрами, указанными выше в autodoc_default_options.

import dataclasses

@dataclasses.dataclass
class Foo:
    """Docstring for Foo

    Attributes:
        var_a (str): An integer.
        var_b (int): A string.
    """
    var_a: str
    var_b: int

В этом случае элементы будут объявлены дважды, по одному разу для каждого расширения, при этом соответствующее объявление reST будет сгенерировано как дубликат. Дублирование объявления reST приведет к обычному предупреждению:

C:\dc.py:docstring для dc.Foo.var_a:1: ПРЕДУПРЕЖДЕНИЕ: дублируется описание объекта dc.Foo.var_a, другой экземпляр в dc, используйте :noindex: для одного из них

C:\dc.py:docstring of dc.Foo.var_b:1: ПРЕДУПРЕЖДЕНИЕ: дублируется описание объекта dc.Foo.var_b, другого экземпляра в dc, используйте :noindex: для одного из них

Здесь можно отметить одно отличие: sphinx-napoleon объявит член в своих собственных раздел docstring, в то время как autodoc будет отображать его как другие элементы. Визуальная разница будет зависеть от темы, например, при использовании темы classic:

введите здесь описание изображения

Наконец, если вы хотите задокументировать участников, использующих sphinx-napoleon, разделы docstring и избегайте дублирования объявления reST из autodoc, сохраняя при этом autodoc_default_options, как показано, вы можете явно использовать параметр :exclude-members: в этой конкретной директиве, например:

dc module
=========

.. autoclass:: dc.Foo
    :exclude-members: var_a, var_b

Будет документировать членов, используя только директивы reST, сгенерированные sphinx-napoleon:

введите здесь описание изображения

person bad_coder    schedule 30.10.2020
comment
Могу ли я как-то настроить exclude-members в conf.py, или мне нужно обновлять .rst каждый раз, когда я запускаю sphinx-apidoc? - person Arne; 30.10.2020
comment
@Arne Я написал довольно обширный пост о трудностях установки параметров autodoc по умолчанию при использовании sphinx-apidoc. Загвоздка в том, что sphinx-apidoc берет параметры по умолчанию из переменной среды, а не в качестве аргумента командной строки... В остальном :exclude-members: можно установить в autodoc_default_flags. Правильный выбор — установить по умолчанию наиболее часто используемый параметр, когда вы хотите, чтобы исключение из правила задавало этот параметр непосредственно в директиве .rst. - person bad_coder; 30.10.2020
comment
спасибо за подробное объяснение и ссылки на ресурсы =) - person Arne; 30.10.2020