这是Sphinx autodoc
中的一个bug,与某些使用Enum的情况有关。
可以通过仔细编写.rst
文件来解决这个问题。
话虽如此,我认为这是针对以下内容的:
![enter image description here](https://istack.dev59.com/UDlJL.webp)
相应的.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."""
MEMBER1 = SomeOtherClass(1)
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']
以启用谷歌风格注释。
到目前为止,已经确定了触发错误的特定条件,包括链接@mzjn提供的链接和您的帖子,即:
- 使用 @classmethod + IntEnum。
- 使用 @classmethod + 多重继承,其中一个父类是 Enum。
需要注意的是:仅使用简单的 Enum + @classmethod 不会触发错误。(在这种情况下,.. autoclass::
的行为符合预期并且几乎处理了所有内容。)
该错误会影响多个autodoc
指令及其选项,导致它们的行为与预期不同。
编写.rst文件所需的解决方法如下:
不要在 Enum 中使用 :undoc-members:
,否则将会出现混乱。如果使用,@classmethod 将始终包含在内,而不会获取描述符或文档字符串,并且使用 :exclude-members:
排除它将无效。
接下来是最问题的部分__init__
。最有效的方法是使用 :exclude-members:
将其排除,同时明确使用 .. automethod:: __init__
。
除此之外:不能在 .rst
文件中使用:automethod:
将 @classmethod 放在__init__
旁边,否则整个 @classmethod 将被“吸收”为 __init__
文档字符串的一部分。
对于我来说最有效的方法是使用 :members:
和 :exclude-members:
明确包含/排除 Enum 的所有部分。这能够保证最佳的一致性和autodoc
指令/选项的行为。
有两个注意事项与使用 Sphinx 记录 Enum 相关:
当记录Enum成员时,为了最佳的一致性,请使用#:
语法而不是三引号'''
或内联#
。原因是后者经常被Sphinx“搞混”甚至丢失。
- 即使使用
..member-order: by source
作为指令选项或配置,上述情况通常也会发生。
最后,如果您想在文档中显示Enum成员的值,就像它们出现在类声明语法中一样。根据我的经验,最好的方法是使用如.rst
中所示的:annotation:
。否则,Enum成员将以以下方式显示在文档中:
![enter image description here](https://istack.dev59.com/iR87N.webp)
使用Python 3.8和Sphinx v2.2.2。