nikkie-ftnextの日記

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

Sphinx、お前、python -m sphinx なんてできたのか!

自作のSphinx拡張 sphinx-new-tab-link にいただいたissueに対応する中で知った小ネタです。

目次

Read the Docsのログを見ていて

:bug: extension fails with latest sphinx · Issue #11 · ftnext/sphinx-new-tab-link · GitHub中のログを見ていました。

自作拡張が原因で落ちている箇所を確認していたところ、ふとコマンドの行に目が止まります。
python -m sphinx -T -b html -d _build/doctrees -D language=en . $READTHEDOCS_OUTPUT/html

python -m sphinx

これは初めて見ました。
私はSphinxをquickstartすることが多く、生成されるMakefileのヘビーユーザです(make html)。
この中ではsphinx-buildというコマンドを呼んでいる1という理解2なのですが、python -m sphinxもあるなんて!

この2つ、違いは何なんでしょう?
私、気になります!

ソースコードを確認

結論を言うと、python -m sphinxsphinx-buildが呼び出す実装は同じです。

python -m sphinx

python -mは、指定したパッケージの__main__.pyを実行できます。
https://docs.python.org/ja/3/library/__main__.html#main-py-in-python-packages

__main__.py will be executed when the package itself is invoked directly from the command line using the -m flag.

Sphinx__main__.pyはこちら
https://github.com/sphinx-doc/sphinx/blob/v7.2.6/sphinx/__main__.py

raise SystemExit(main(sys.argv[1:]))

sphinx.cmd.build.mainsys.argvを渡して実行しています(そうか、raise SystemExitなんて書けるのか!)

sphinx.cmd.build.mainはこちら
https://github.com/sphinx-doc/sphinx/blob/v7.2.6/sphinx/cmd/build.py#L325

sphinx-buildコマンド

プロジェクトのメタデータを記載しているpyproject.tomlを見ます3
https://github.com/sphinx-doc/sphinx/blob/v7.2.6/pyproject.toml#L105

[project.scripts]
sphinx-build = "sphinx.cmd.build:main"

sphinx-buildコマンドの実体は、sphinx/cmd/build.pyのmain関数です。
python -m sphinxで呼ばれる関数とおんなじだ!

終わりに

python -m sphinxsphinx-buildコマンドと同じでした。

以下の環境で、(usageの行を除いて)同じヘルプメッセージを確認できました。

2つある経緯が少し気になるところです。
リポジトリの中を探せば見つかるかな?

issue対応も頑張ります!(こんな情報量に満ちたissueをいただけただけで、もう感謝しかないんですが😭)