Sphinx未记录复杂的Enum类

问题描述 投票:1回答:1

在我的代码中,我有一些复杂的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

[当我现在使用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)

但是这也不起作用。

如何使狮身人面像文档成为此类类?

python enums python-sphinx autodoc
1个回答
0
投票

这是Sphinx autodoc中的错误,由于使用了Enum而发生。

可以通过精心编写.rst文件的解决方法来解决。

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

enter image description here

对应的.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__

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

from enum import Enum


class SomeOtherClass:
    """ SomeOtherClass documentation """

    def __init__(self, other_arg):
        """Example of docstring on the __init__ method.

        Args:
            other_arg (int): Description of `other_arg`.
        """
        self.other_arg = other_arg


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

    #: :py:mod:`~my_package.my_module.SomeOtherClass`: MEMBER1 docstring comment.
    MEMBER1 = SomeOtherClass(1)
    #: :py:mod:`~my_package.my_module.SomeOtherClass`: MEMBER2 docstring comment.
    MEMBER2 = SomeOtherClass(2)

    def __init__(self, complex_arg):
        """Example of docstring on the __init__ method.

        Args:
            complex_arg (int): Description of `complex_arg`.
        """
        self.complex_arg = complex_arg
        super().__init__(complex_arg)

    def some_method(self):
        """The doc of some_method."""
        pass

    @classmethod
    def some_classmethod(cls, some_arg):
        """The doc of some_classmethod.

        Args:
            some_arg (int): Description of `some_arg`.
        """
        pass

您的conf.py可以保留为标准格式,我只添加了extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']以启用Google样式注释。



到目前为止,

具体的引发错误的条件组合在@mzjn提供的链接中以及您的帖子中都已标识,即:

  1. 使用@classmethod + IntEnum。
  2. 使用@classmethod +多重继承,父母之一是Enum。

应该注意:使用带有@classmethod的简单枚举不会触发该错误。 (在这种情况下,.. autoclass::的行为符合预期,几乎可以处理所有事情。)



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

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

  1. 请勿在枚举中使用:undoc-members:,否则caos会爆发。如果这样做,则始终包含@classmethod而不选择描述符或文档字符串,而用:exclude-members:排除它将无效。

  2. 下一个__init__是最有问题的方面。有效的方法是用:exclude-members:排除它,并明确地使用.. automethod:: __init__

  3. 与以上内容一起:您不能在__init__中使用:automethod:将@classmethod放在.rst旁边,否则整个@classmethod将被“吸收”作为__init__文档字符串的一部分。

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



[两个后记] >> 与记录枚举有关使用Sphinx(与bug没有直接关系)。

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

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

  3. enter image description here

将Python 3.8与Sphinx v2.2.2。一起使用

© www.soinside.com 2019 - 2024. All rights reserved.