開發 autodoc 擴充功能¶
本教學的目標是建立一個擴充功能,為 autodoc 新增對新類型的支援。此 autodoc 擴充功能將格式化 Python 標準函式庫中的 IntEnum
類別。(模組 enum
)
概觀¶
我們希望擴充功能可以為 IntEnum 建立自動文件。IntEnum
是標準函式庫 enum
模組中的整數列舉類別。
目前此類別沒有特殊的自動文件行為。
我們希望將以下內容新增至 autodoc
一個新的
autointenum
指令,將會文件化IntEnum
類別。產生的文件將包含所有可能的列舉值及其名稱。
autointenum
指令將有一個:hex:
選項,這會導致整數以十六進位格式印出。
先決條件¶
我們需要與先前的擴充功能相同的設定。這次,我們將把我們的擴充功能放在一個名為 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()
方法會註冊我們新的自動文件編寫器類別。
我們想要從 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
在 autodoc 擴充功能中有幾個不同的文件編寫器類別,例如 MethodDocumenter
或 AttributeDocumenter
,但我們的新類別是 ClassDocumenter
的子類別,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 ) -> 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
此方法產生類別文件的本文。在呼叫 super 方法之後,我們為列舉描述產生行。
使用擴充功能¶
你現在可以使用新的 autodoc 指令來文件化任何 IntEnum
。
例如,你有以下的 IntEnum
class Colors(IntEnum):
"""Colors enumerator"""
NONE = 0
RED = 1
GREEN = 2
BLUE = 3
這將會是包含自動文件指令的文件檔案
.. autointenum:: my_enums.Colors
延伸閱讀¶
如果你希望在多個專案或與他人分享你的擴充功能,請查看第三方擴充功能章節。