Sphinx 没有记录复杂的 Enum 类

Rit*_*tel 4 python enums python-sphinx autodoc

在我的代码中,我有一些复杂的 Enum 类型的类。例如:

class ComplexEnum(SomeOtherClass, Enum):
    """ Some documentation """

    MEMBER1 = SomeOtherClass(1)
    MEMBER2 = SomeOtherClass(2)

    def __init__(self, arg):
        """ more doc """
        pass

    def somemethod(self):
        """ more doc """
        pass

    @classmethod
    def someclassmethod(cls, otherparam):
        """ more doc """
        pass
Run Code Online (Sandbox Code Playgroud)

当我现在使用 autodoc 用 Sphinx 创建我的文档时,这个类被跳过了。我尝试将这样的自定义文档添加到我的 conf.py 文件中:

from sphinx.ext.autodoc import ClassDocumenter

class MyClassDocumenter(ClassDocumenter):
    objtype = 'ComplexEnum'
    directivetype = 'class'

    @classmethod
    def can_document_member(cls, member, membername, isattr, parent):
        return isinstance(member, ComplexEnum)

def setup(app):
    app.add_autodocumenter(MyClassDocumenter)
Run Code Online (Sandbox Code Playgroud)

但这也不起作用。

我怎样才能让 sphinx 记录那些类?

bad*_*der 5

这是 Sphinx 中的一个错误,在autodoc使用 Enum 时发生。

它可以通过仔细的解决方法来解决写入.rst文件。

话虽如此,我认为这是针对:

在此处输入图片说明

相应的.rst

my_module module
================

.. automodule:: my_module
   :exclude-members: ComplexEnum


   .. autoclass:: ComplexEnum
      :members: some_method
      :show-inheritance:
      :exclude-members: MEMBER1, MEMBER2, __init__, some_classmethod

      .. automethod:: some_classmethod  

      .. autoattribute:: MEMBER1
         :annotation: = SomeOtherClass(1)

      .. autoattribute:: MEMBER2
         :annotation: = SomeOtherClass(2)

      .. automethod:: __init__

   .. autoclass:: SomeOtherClass
      :special-members: __init__

Run Code Online (Sandbox Code Playgroud)

我稍微修改了代码以更好地解释解决方法的一些细节:

my_module module
================

.. automodule:: my_module
   :exclude-members: ComplexEnum


   .. autoclass:: ComplexEnum
      :members: some_method
      :show-inheritance:
      :exclude-members: MEMBER1, MEMBER2, __init__, some_classmethod

      .. automethod:: some_classmethod  

      .. autoattribute:: MEMBER1
         :annotation: = SomeOtherClass(1)

      .. autoattribute:: MEMBER2
         :annotation: = SomeOtherClass(2)

      .. automethod:: __init__

   .. autoclass:: SomeOtherClass
      :special-members: __init__

Run Code Online (Sandbox Code Playgroud)

conf.py可以保持标准,我只添加extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']了启用谷歌风格的评论。



到目前为止,在@mzjn 贡献的链接和您的帖子中确定了触发错误的特定条件组合,即:

  1. 使用@classmethod + IntEnum。
  2. 使用@classmethod + 多重继承,父对象之一是枚举。

应该注意:使用带有 @classmethod 的简单 Enum 不会触发错误。(在这种情况下,它.. autoclass::会按预期运行并处理几乎所有事情。)



该错误会影响多个autodoc指令及其选项,导致它们出现意外行为。

编写 .rst的必要解决方法如下:

  1. 不要:undoc-members:在 Enum 中使用,否则 caos 会爆发。如果你这样做了,@classmethod with 总是被包含在不获取描述符或文档字符串的情况下,并且将它排除在外:exclude-members:将不起作用。

  2. 接下来__init__是最有问题的方面。有效的是将它排除在外:exclude-members:,并明确使用.. automethod:: __init__.

  3. 连同上面的:你不能把@classmethod旁边__init__使用:automethod:.rst,否则整个@classmethod获得“absorved”作为一部分__init__文档字符串。

  4. 对我来说,最有效的方法是使用:members:和明确包含/排除 Enum 的所有部分:exclude-members:。这保证了autodoc指令/选项行为的最佳一致性。



两个最后的音符相关的记录枚举的使用狮身人面像(不直接相关的bug)。

  1. 在记录 Enum 成员时,为了获得最佳一致性,请使用#:语法而不是三重引号'''或 inline #。原因是,因为后者经常被Sphinx“混淆”甚至丢失。

    • 即使..member-order: by source用作指令选项或在配置中使用,上述情况通常也是如此。
  2. 最后,如果您希望 Enum 成员的值显示在文档中,就像它们出现在类声明语法中一样。最好的办法,以我的经验,是使用:annotation:如图所示.rst。否则,枚举成员将在文档中显示如下:

在此处输入图片说明

使用 Python 3.8 和 Sphinx v2.2.2。