autodoc 拡張機能の開発¶
このチュートリアルの目的は、autodoc に新しいタイプサポートを追加する拡張機能を作成することです。この autodoc 拡張機能は、Python 標準ライブラリ(モジュール enum
)の IntEnum
クラスをフォーマットします。
概要¶
私たちは、IntEnum の自動ドキュメントを作成する拡張機能を望んでいます。IntEnum
は、標準ライブラリ enum
モジュールの整数 enum クラスです。
現在、このクラスには特別な自動ドキュメントの動作はありません。
autodoc に以下の機能を追加したいと考えています。
IntEnum
クラスを記述する新しいautointenum
ディレクティブ。生成されたドキュメントには、名前付きのすべての enum の可能な値が含まれます。
autointenum
ディレクティブには、:hex:
オプションがあり、整数が 16 進数形式で表示されます。
前提条件¶
前の拡張機能 と同じ設定が必要です。今回は、autodoc_intenum.py
というファイルに拡張機能を配置します。my_enums.py
には、記述するサンプル enum が含まれます。
取得する可能性のあるフォルダ構造の例を以下に示します。
└── 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, Any
5
6from sphinx.ext.autodoc import ClassDocumenter, bool_option
7
autodoc 拡張機能には、MethodDocumenter
や AttributeDocumenter
などのさまざまなドキュメンタークラスがありますが、新しいクラスは、autodoc がクラスの記述に使用するドキュメンタークラスである ClassDocumenter
のサブクラスです。
新しい自動ドキュメンタークラスの定義を以下に示します。
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)
新しいクラスの重要な属性
- objtype
この属性は、「auto」ディレクティブ名を決定します。この場合、auto ディレクティブは
autointenum
になります。- directivetype
この属性は、生成されるディレクティブ名を設定します。この例では、生成されるディレクティブは
.. :py:class::
になります。- priority
数値が大きいほど、優先度が高くなります。親よりも優先度が高くなるようにしたいと考えています。
- option_spec
オプションの仕様。親クラスのオプションをコピーし、新しいオプション *hex* を追加します。
オーバーライドされたメンバー
- can_document_member
このメンバーのオーバーライドが重要です。渡されたオブジェクトがこのクラスで記述できる場合は *True* を返す必要があります。
- add_directive_header
このメソッドは、ディレクティブヘッダーを生成します。:final: ディレクティブオプションを追加します。ディレクティブが生成されないように、**super** を呼び出すことを忘れないでください。
- add_content
このメソッドは、クラスドキュメントの本文を生成します。super メソッドを呼び出した後、enum 説明の行を生成します。
拡張機能の使用¶
これで、新しい autodoc ディレクティブを使用して、任意の IntEnum
を記述できるようになりました。
たとえば、次の IntEnum
があるとします。
class Colors(IntEnum):
"""Colors enumerator"""
NONE = 0
RED = 1
GREEN = 2
BLUE = 3
自動ドキュメントディレクティブを含むドキュメントファイルは次のようになります。
.. autointenum:: my_enums.Colors
参考資料¶
複数のプロジェクト間または他の人と拡張機能を共有したい場合は、サードパーティ製拡張機能 セクションを確認してください。