本文介绍了Sphinx没有记录复杂的Enum类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my code I have some classes that are complex Enum types. For example:

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文件中:

When I now create my documentation with Sphinx using autodoc this class is just skipped. I tried adding a custom documenter like this to my conf.py file:

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)

但这也不起作用。

我如何使狮身人面像文件

How can I make sphinx document those kind of classes?

推荐答案

这是Sphinx autodoc 中的错误与Enum的某些用法有关。

This is a bug in Sphinx autodoc occurring with some uses of Enum.

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

It can be solved by careful workarounds writing the .rst files.

话虽如此,我认为这是为了:

Having said that, I assume this is aimed for:

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

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

I slightly altered the code to better explain some details of the workarounds:

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风格的评论。

Your conf.py can be left standard, I only added extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon'] to enable google style comments.

特定的到目前为止,可以在@mzjn提供的链接中以及您的帖子中找到触发该错误的条件的组合,即:


  1. 使用@classmethod + IntEnum。

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

应注意:使用带有@classmethod的简单枚举不会触发该错误(在这种情况下, .. autoclass :: 的行为与预期相同,

It should be noted: using a simple Enum with @classmethod does not trigger the bug. (In that case .. autoclass:: behaves as expected and takes care of almost everything.)

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

The bug affects several autodoc directives and their options, causing them to have unexpected behavior.

其他编写.rst的基本解决方法如下:

The necessary workarounds in writing the .rst are as follows:


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

  1. DO NOT use :undoc-members: in the Enum, or else caos breaks out. If you do, the @classmethod with always be included without picking up the descriptor or the docstring, and excluding it with :exclude-members: will have no effect.

下一步 __ init __ 是最有问题的方面。有效的方法是使用:exclude-members:排除它,同时明确地使用 .. automethod :: __init __

Next __init__ is the most problematic aspect. What worked was excluding it with :exclude-members:, together with explicitly using .. automethod:: __init__.

与此同时,您不能使用<$ c将@classmethod放在 __ init __ 旁边$ c>:automethod:在 .rst 中,否则整个@classmethod被吸收作为 __ init __ 文档字符串。

Together with the above: you CAN NOT put the @classmethod next to __init__ using :automethod: in the .rst, or else the entire @classmethod gets "absorved" as part of the __init__ docstring.

对我来说,最有效的方法是使用<$ c显式包括/排除枚举的所有部分$ c>:成员:和:exclude-members:。这保证了 autodoc 指令/选项的行为的最佳一致性。

What worked best, for me, is including/excluding all parts of the Enum explicitly with :members: and :exclude-members:. That guarantees the best consistency to the behavior of the autodoc directives/options.









两个最后注释 与使用Enum记录有关Sphinx(与错误没有直接关系)。



Two last notes are pertinent to documenting Enum's using Sphinx (not directly related to the bug).


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

  1. When documenting Enum members, for best consistency use #: syntax instead of triple-quotes ''' or inline #. The reason is, because the later are frequently "mixed-up" or even lost by Sphinx.


  • 即使使用 .. member-order:按来源作为指令选项或在配置中。

  • The above is usually so even if using ..member-order: by source as a directive option or in the configurations.

最后,如果您希望显示Enum成员的值在文档中,它们出现在类声明语法中。以我的经验,最好的方法是使用:annotation:,如 .rst 所示。否则,Enum成员将在这样的文档中显示:

Finally, in case you want the values of the Enum members to show in the documentation, as they appear in the class declaration syntax. The best way, in my experience, is using an :annotation: as shown in the .rst. Or else, the Enum members will show in documentation like this:

在Sphinx v2.2.2中使用Python 3.8

Using Python 3.8 with Sphinx v2.2.2.

这篇关于Sphinx没有记录复杂的Enum类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 04:29