Sphinx 没有记录复杂的枚举 类
Sphinx not documenting complex Enum classes
在我的代码中,我有一些 class 是复杂的枚举类型。例如:
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 创建我的文档时,这个 class 被跳过了。我尝试将这样的自定义文档添加到我的 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)
但这也不行。
我怎样才能使 sphinx 记录那些 classes?
这是 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__
我稍微修改了代码以更好地解释解决方法的一些细节:
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风格的评论。
到目前为止,在 link @mzjn 贡献的 link 和您的 post 中,确定了触发错误 的具体 条件组合,即:
- 使用@class方法+ IntEnum.
- 使用@class方法+多重继承,父类之一为Enum
需要注意的是:使用带有@class方法的简单枚举不会触发错误。 (在这种情况下,.. autoclass::
的行为与预期一致,几乎可以处理所有事情。)
该错误会影响多个 autodoc
指令及其选项,导致它们出现意外行为。
编写 .rst 的必要解决方法如下:
不要在 Enum 中使用 :undoc-members:
,否则会发生 caos。如果你这样做,@class 方法始终被包含而不获取描述符或文档字符串,并且用 :exclude-members:
排除它不会有任何效果。
接下来__init__
是最有问题的方面。有效的方法是用 :exclude-members:
排除它,并明确使用 .. automethod:: __init__
。
连同上面的:你不能把@class方法放在__init__
旁边,在.rst
中使用:automethod:
,否则整个@class方法得到"absorved"作为__init__
文档字符串的一部分。
对我来说,最有效的是 including/excluding Enum 的所有部分明确地使用 :members:
和 :exclude-members:
。这保证了 autodoc
directives/options.
行为的最佳一致性
两个 最后的笔记 与使用 Sphinx 记录 Enum 的 有关(与错误没有直接关系)。
在记录 Enum 成员时,为了获得最佳一致性,请使用 #:
语法而不是三引号 '''
或内联 #
。原因是,因为后者经常"mixed-up"甚至被Sphinx丢掉。
- 即使将
..member-order: by source
作为指令选项或在配置中使用,通常也是如此。
最后,如果您希望 Enum 成员的值显示在文档中,就像它们出现在 class 声明语法中一样。根据我的经验,最好的方法是使用 :annotation:
,如 .rst
所示。否则,枚举成员将在文档中显示如下:
使用 Python 3.8 和 Sphinx v2.2.2。
在我的代码中,我有一些 class 是复杂的枚举类型。例如:
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 创建我的文档时,这个 class 被跳过了。我尝试将这样的自定义文档添加到我的 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)
但这也不行。
我怎样才能使 sphinx 记录那些 classes?
这是 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__
我稍微修改了代码以更好地解释解决方法的一些细节:
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风格的评论。
到目前为止,在 link @mzjn 贡献的 link 和您的 post 中,确定了触发错误 的具体 条件组合,即:
- 使用@class方法+ IntEnum.
- 使用@class方法+多重继承,父类之一为Enum
需要注意的是:使用带有@class方法的简单枚举不会触发错误。 (在这种情况下,.. autoclass::
的行为与预期一致,几乎可以处理所有事情。)
该错误会影响多个 autodoc
指令及其选项,导致它们出现意外行为。
编写 .rst 的必要解决方法如下:
不要在 Enum 中使用
:undoc-members:
,否则会发生 caos。如果你这样做,@class 方法始终被包含而不获取描述符或文档字符串,并且用:exclude-members:
排除它不会有任何效果。接下来
__init__
是最有问题的方面。有效的方法是用:exclude-members:
排除它,并明确使用.. automethod:: __init__
。连同上面的:你不能把@class方法放在
__init__
旁边,在.rst
中使用:automethod:
,否则整个@class方法得到"absorved"作为__init__
文档字符串的一部分。对我来说,最有效的是 including/excluding Enum 的所有部分明确地使用
:members:
和:exclude-members:
。这保证了autodoc
directives/options. 行为的最佳一致性
两个 最后的笔记 与使用 Sphinx 记录 Enum 的 有关(与错误没有直接关系)。
在记录 Enum 成员时,为了获得最佳一致性,请使用
#:
语法而不是三引号'''
或内联#
。原因是,因为后者经常"mixed-up"甚至被Sphinx丢掉。- 即使将
..member-order: by source
作为指令选项或在配置中使用,通常也是如此。
- 即使将
最后,如果您希望 Enum 成员的值显示在文档中,就像它们出现在 class 声明语法中一样。根据我的经验,最好的方法是使用
:annotation:
,如.rst
所示。否则,枚举成员将在文档中显示如下:
使用 Python 3.8 和 Sphinx v2.2.2。