Poetry の scripts はタスクランナー機能ではない

要約

  • Poetry には現在(1.0.3)、 npm run <task name>pipenv run <task name> のようなタスクを実行する機能はない
  • tool.poetry.scripts セクションは ユーザーに提供するコマンド名や実行ファイル を指定するセクション
    • 開発者が使うためのものではない

scripts 機能とは何か

特定の記事を挙げることはしませんが、ときおり Poetry の scripts 機能を使ってタスクランナーのような機能を実現している記事を見かけます。例えば、Web アプリの開発で poetry run runserver でテスト用サーバを起動したりとか。

しかし、Poetry の公式ドキュメントによれば、この機能はタスクランナーのために作られた機能では ありません。この機能について、次のように説明されています。

This section describe the scripts or executable that will be installed when installing the package

すなわち、あなたが開発しているパッケージが インストールされた際 に、実行コマンド名を制御するものです。開発者が使うタスクではなく、 パッケージをインストールしたユーザーが使うコマンド名(エントリーポイント)を定義するためのもの です。だから Python スクリプトしか指定できません(Python パッケージのエントリーポイントですから)。

そもそもですが、Poetry はパッケージの依存関係の管理、パッケージのビルド、パッケージの公開をするためのツールです。タスクを管理する機能はありません1

なぜこのような誤解が起こったか

推測ですが、考えられることとしては Pipenv(Pipfile) の scripts セクションの存在があると思います。Pipenv では既にタスクランナーのような機能が導入されていて、その機能を使うためのPipfile(TOMLファイル)のセクションの名前は scripts です2

しかしおそらく Poetry における scripts の名前の由来は setup.py の console_scripts でしょう3。この機能は上に書いたように「パッケージがインストールされた際のエントリーポイント」を定義するためのキーワードです。

scripts という同じ名前ですが、全く異なる機能です。しかし同じ名前であるがゆえに、Pipenv から Poetry に乗り換えようとした人が “scripts” 機能を探し、異なる機能であることに気づかずそのまま利用してしまった、という流れなのだと思います。

ちなみにですが、この議論を眺めている限りみんな混乱していそうなので、日本人が英語苦手だから起こった問題というわけでもないようです。

タスクランナーとして利用する副作用

副作用としては、下記のことが考えられます。下記のようにコマンドが定義してあったとしましょう。

[tool.poetry.scripts]
start = "util:start"
stop = "util:stop"

このパッケージで poetry buildpoetry publish をしたとします。その際、ユーザーはこのパッケージをインストールすると start コマンドと stop コマンドを意図せずインストールしてしまうことになります。ユーザーのコマンドの名前空間を侵す行為であり、行儀の悪いパッケージです4

とはいえタスク定義したい

現状の Poetry では公式に提供されているタスク定義をする方法は存在しません。ad-hoc な方法を続けるか、Pipenv など別のツールを使うか、Poetry と Makefile などを併用するか、Poetry の開発を待つしかありません。もちろん、Poetry の開発に何らかの形で参加するのも手です。プラグイン機構の議論があるので、それに参加するのが最も近道でしょう。

一般に Pipenv などに向いているフローが Poetry にも向いているとは限りません。Poetry はパッケージの開発5については強力なサポートをしてくれていますが、Web アプリケーションなどの開発に十分な機能が提供されているとはわたしも思っていません。複雑なタスクは Makefile を書くなどしてカバーしています。

Poetry がモノリシックなコマンドになり、何でもできるようになる未来が本当に良いものかどうかはわたしにはわかりません。そうした未来を志向する人はそのように活動すればいいと思いますし、わたしは今のシンプルな、機能が足りないと思わせるくらいのPoetryで、実はちょうど良いんじゃないかと思っています。


  1. 実際、npm-scriptsのようにタスクを実行するための機能が提案されたことがありましたが、リジェクトされました。 https://github.com/python-poetry/poetry/pull/591 ↩︎

  2. とはいえ、この scripts セクションの名前もまた npm とかだったりしそうです。そこまでは追っていません。 ↩︎

  3. 参考 pypiにパッケージを登録して、setup.pyの「scripts」と「console_scripts」の違いを比較してみた - カイワレの大冒険 Third ↩︎

  4. とはいえ、そもそもパッケージ開発者はこのような誤解をしておらず、主にアプリケーション開発に Poetry を利用している人が誤解していそうなことなので、内心あまりこれが問題になることはないんじゃないかと思いながら書いています(そもそもこの勘違いをしている人は poetry publish をしないと思われるため)。 ↩︎

  5. PyPI にアップロードされるようなもの、ライブラリやフレームワーク。 ↩︎