开发autodoc扩展

本教程的目标是创建一个扩展,添加对AutoDoc新类型的支持。此AutoDoc扩展名将格式化 IntEnum 类来自于Python标准库。(模块 enum )

概述

我们想要的扩展将创建IntEnum的自动文档。 IntEnum 是标准库中的整数枚举类 enum 模块。

目前,此类没有特殊的自动文档行为。

我们希望在AutoDoc中添加以下内容:

  • 一种新的 autointenum 指令,它将记录 IntEnum 班级。

  • 生成的文档将包含所有可能的枚举值和名称。

  • 这个 autointenum 指令将有一个选项 :hex: 这将导致以十六进制形式打印整数。

先决条件

我们需要与中相同的设置 the previous extensions .这次,我们将在一个名为 autodoc_intenum.py .的 my_enums.py 将包含我们将记录的示例列举。

以下是您可能获得的文件夹结构的示例:

└── source
    ├── _ext
    │   └── autodoc_intenum.py
    ├── conf.py
    ├── index.rst
    └── my_enums.py

正在编写扩展

开始于 setup 函数用于扩展。

1def setup(app: Sphinx) -> ExtensionMetadata:
2    app.setup_extension('sphinx.ext.autodoc')  # Require autodoc extension
3    app.add_autodocumenter(IntEnumDocumenter)
4    return {
5        'version': '1',
6        'parallel_read_safe': True,
7    }

这个 setup_extension() 方法将拉出AutoDoc扩展,因为我们的新扩展依赖于AutoDoc。 add_autodocumenter() 是注册新的AUTO文档管理器类的方法。

我们希望从AutoDoc扩展中导入某些对象:

1from __future__ import annotations
2
3from enum import IntEnum
4from typing import TYPE_CHECKING
5
6from sphinx.ext.autodoc import ClassDocumenter, bool_option
7

有几个不同的文档管理器类,例如 MethodDocumenterAttributeDocumenter 在AutoDoc扩展中可用,但我们的新类是 ClassDocumenter AutoDoc使用哪个Documenter类来对类进行文档记录。

这是我们新的自动文档管理器类的定义:

 1class IntEnumDocumenter(ClassDocumenter):
 2    objtype = 'intenum'
 3    directivetype = ClassDocumenter.objtype
 4    priority = 10 + ClassDocumenter.priority
 5    option_spec = dict(ClassDocumenter.option_spec)
 6    option_spec['hex'] = bool_option
 7
 8    @classmethod
 9    def can_document_member(
10        cls, member: Any, membername: str, isattr: bool, parent: Any
11    ) -> bool:
12        try:
13            return issubclass(member, IntEnum)
14        except TypeError:
15            return False
16
17    def add_directive_header(self, sig: str) -> None:
18        super().add_directive_header(sig)
19        self.add_line('   :final:', self.get_sourcename())
20
21    def add_content(
22        self,
23        more_content: StringList | None,
24    ) -> None:
25        super().add_content(more_content)
26
27        source_name = self.get_sourcename()
28        enum_object: IntEnum = self.object
29        use_hex = self.options.hex
30        self.add_line('', source_name)
31
32        for the_member_name, enum_member in enum_object.__members__.items():  # type: ignore[attr-defined]
33            the_member_value = enum_member.value
34            if use_hex:
35                the_member_value = hex(the_member_value)
36
37            self.add_line(f'**{the_member_name}**: {the_member_value}', source_name)
38            self.add_line('', source_name)

新类的重要属性:

objtype

此属性确定 auto 指令名称。在本例中,AUTO指令将为 autointenum

directivetype

该属性设置生成的指令名称。在本例中,生成的指令将是 .. :py:class::

priority

数字越大,优先级越高。我们希望我们的纪录员优先于父级。

option_spec

选项规格。我们复制父类选项并添加一个新选项 hex

被覆盖的成员:

can_document_member

重写此成员非常重要。它应该会回来 True 传递的对象可以由此类记录的时间。

add_directive_header

此方法生成指令头。我们添加了 :final: 指令选项。记得给我打电话 super 否则将不会生成任何指令。

add_content

此方法生成类文档的主体。在调用超方法之后,我们生成用于枚举描述的行。

使用扩展模块

现在,您可以使用新的AutoDoc指令来记录任何 IntEnum

例如,您具有以下内容 IntEnum

my_enums.py
class Colors(IntEnum):
    """Colors enumerator"""
    NONE = 0
    RED = 1
    GREEN = 2
    BLUE = 3

这将是带有自动文档指令的文档文件:

index.rst
.. autointenum:: my_enums.Colors

进一步阅读

如果您希望跨多个项目或与其他人共享您的扩展,请查看 第三方扩展 科.