开发autodoc扩展

本教程的目标是创建一个扩展,以支持自动文档的新类型.这个自动文档扩展将格式化来自Python标准库的 IntEnum 类.(模块 enum

概述

我们希望这个扩展可以为 IntEnum 创建自动文档. IntEnum 是标准库 enum 模块中的整数枚举类.

目前该类没有特别的自动文档行为.

我们想要将以下内容添加到自动文档中:

  • 一个新的 autointenum 指令,将用于文档记录 IntEnum 类.

  • 生成的文档将包含所有枚举的可能值及其名称.

  • The autointenum directive will have an option :hex: which will cause the integers be printed in hexadecimal form.

先决条件

我们需要与 之前的扩展 相同的设置.这一次,我们将在一个名为 autodoc_intenum.py 的文件中推出扩展.:file: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    }

The setup_extension() method will pull the autodoc extension because our new extension depends on autodoc. add_autodocumenter() is the method that registers our new auto documenter class.

我们想要从autodoc扩展中导入某些对象:

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

在autodoc扩展中,有几种不同的文档生成器类,如 MethodDocumenterAttributeDocumenter ,但我们的新类是 ClassDocumenter 的子类,这是一个用于通过autodoc文档化类的文档生成器类.

这是我们新的自动文档生成器类的定义:

 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        no_docstring: bool = False,
25    ) -> None:
26        super().add_content(more_content, no_docstring)
27
28        source_name = self.get_sourcename()
29        enum_object: IntEnum = self.object
30        use_hex = self.options.hex
31        self.add_line('', source_name)
32
33        for the_member_name, enum_member in enum_object.__members__.items():
34            the_member_value = enum_member.value
35            if use_hex:
36                the_member_value = hex(the_member_value)
37
38            self.add_line(f'**{the_member_name}**: {the_member_value}', source_name)
39            self.add_line('', source_name)

新类的重要属性:

对象类型

此属性决定了 auto 指令的名称.在此情况下,auto 指令将是 autointenum .

指令类型

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

优先级

数字越大,优先级越高.我们希望我们的文档优先级高于父级.

选项规范

选项规范.我们复制父类的选项并添加一个新选项 hex.

重载的成员:

can_document_member

此成员很重要,必须重写.当传入的对象可以被此类文档化时,应该返回 True.

添加指令头部

这个方法生成指令头.我们添加了 :final: 指令选项.请记得调用 super,否则将不会生成指令.

添加内容

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

使用扩展

您现在可以使用新的 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

进一步阅读

如果您希望在多个项目之间或与他人共享您的扩展,请查看 第三方扩展 部分.