nikkie-ftnextの日記

イベントレポートや読書メモを発信

Mixinを継承したクラスを動的に生成する機能を提供して、Sphinx拡張開発を簡単にする 襲(sphinxcontrib-extdevhelper-kasane)をリリースしました👘

リリース報告エントリです。
sphinxcontrib-extdevhelper-kasaneが爆誕しました!

目次

sphinxcontrib-extdevhelper-kasane(現在 0.2.0)

sphinx-new-tab-link 0.3.0の「動的にクラスを生成して、Translatorに指定する」実装をkasaneとして切り出しました。

kasaneに至るまで

Mixinを継承したクラスを動的に生成する機能は、pydata-sphinx-themeのソースコードから知ったものです。

ビルダーに指定されたトランスレイターのクラスにMixinを継承させ、できたクラスをビルダーに再設定します。
sphinx-new-tab-linkに実装しましたが、(パッケージとしては未公開の)手元の拡張でも動的に継承する実装を使いたく、「2箇所で使うなら」とパッケージとして抽出しました。

kasaneが提供するSphinx拡張開発体験

kasaneを使うことで、sphinx-new-tab-linkの実装はこのようになりました。

from sphinxcontrib.kasane import new_translator_class_for_builder

def setup(app: Sphinx):
    html_translator_handler = new_translator_class_for_builder(
        "html", NewTabLinkHTMLTranslatorMixin, "NewTabLinkHTMLTranslator"
    )
    app.connect("builder-inited", html_translator_handler)

new_translator_class_for_builder()はbuilder-inited(などのイベント)に指定できる、appを引数とする関数を返します。
「フォーマットがhtmlのビルダーであれば、NewTabLinkHTMLTranslatorMixinを動的に継承してNewTabLinkHTMLTranslatorクラスを作る関数」をここでは指定しています。

フォーマットだけでなく、ビルダーの名前を指定して動的に継承できるようにも実装しました。
こちらはsphinx-revealjs製のスライドのリポジトリ1で設定しています。

kasaneによって、Sphinx拡張で使うMixinの動的な継承が簡単に書けるようにできました!

pydata-sphinx-themeのソースに見つけた実装は、独自のMixinで実装したSphinx拡張をフォーマットがHTMLの任意のビルダーと合わせて使えるようにするものでした。
これをラップしてeasyにしようという試みがkasaneです。
Sphinx開発を始めたばかりで右も左も分からなかった過去の私がkasaneを使ったら、v0.3.0相当のsphinx-new-tab-linkを初手で作れるんじゃないかと思います

終わりに

sphinxcontrib-extdevhelper-kasaneリリースの報告でした。
Sphinx拡張開発でTranslatorに独自のMixinを継承させたいとき、動的なクラス生成というちょっとややこしい部分をkasaneが代わりに担ってくれます。

触ってみた感想や「こういうユースケースで使いたいんだけどサポートしてくれないか」といった要望、そしてリポジトリへのスターも、お待ちしています!

sphinx-new-tab-linkともども、応援ください

1本紹介したぞ〜(1/3)

P.S. 機を同じくしてsphinx-revealjsのattakeiさんも

Sphinx拡張開発のヘルパーライブラリのリポジトリを公開されています2

2つのデコレータを提供していますね。
https://github.com/atsphinx/helper/blob/v0.1.0/src/atsphinx/helper/decorators.py

  • @setup_only
  • @emit_only

精読させていただきます!