Poetry: Python の依存関係管理とパッケージングを支援するツール

Python には依存関係を管理するツールがたくさんあります。 Python も歴史あるプログラミング言語なので仕方ないですが、情報が多すぎて特に初心者は混乱してしまいます。 結局の所、pip、virtualenv (venv) を使えば十分な場合が多いので、まずはこれらの使い方を学習しましょう。

近頃は Pipenv という依存関係管理ツールが登場して人気です。 日本語でも Pipenv の情報をよく見かけるようになりました。 さらに、最近になって Poetry という依存関係管理とパッケージングを支援するツールが登場しました。 意外と Poetry に関する日本語の情報がないようなので、簡単に紹介してみようと思います。

各ツールの機能をまとめた表 が公開されていたので参考にしてください。

Pipenv

2017 年 1 月に Pipenv というツールが登場しました。 Pipenv については既に日本語の情報がたくさんあります。 Pipenv は pip と virtualenv (venv) をまとめたようなツールです。 Node.js のパッケージ管理ツールの npm などに似ています。

Pipenv は環境にインストールしたパッケージのバージョン情報を、requirements.txt に代わって Pipfile (Pipfile.lock) というファイルで管理します。 従来の requirements.txt を使う方法では、依存関係に問題が出る場合には手動で requirements.txt を記述する必要があります。 また、パッケージをインストールなどしても、requirements.txt が自動で更新されることはありません。 一方で Pipenv はパッケージをインストールする際に依存関係を解決し、適切なバージョンのものをインストールします。 また、Pipfile と Pipfile.lock を自動で更新します。

Pipenv は 2017 年 11 月に PyPA (python.org) 公式の推奨ツールと宣伝されるようになります。 これにより Pipenv を使う人が増えましたが、後に公式推奨ツールという点で揉めることになります。

Poetry

2018 年 2 月に Poetry というツールが登場しました。 Poetry は Rust のパッケージ管理ツールの Cargo などに似ています。

Pipenv は requirments.txt を置き変え、依存関係を管理するツールです。 パッケージを配布するためには setup.py や setup.cfg などを管理する必要があることは変わりません。 一方の Poetry は依存関係の管理だけでなく、パッケージングも支援します。 Poetry は PEP 518 で標準化された pyproject.toml というファイルを使用します。 そして、pyproject.toml (pyproject.lock) で requirements.txt だけでなく、setup.py、setup.cfg、MANIFEST.in を置き換えます。 ちなみに、Pipfile の仕様は PEP で決まったものではなく、ドキュメント にも確定したものではないことが書かれています。 Poetry は requirements.txt だけでなく setup.py などを管理する手間を軽減できるうえ、Pipenv よりも依存関係の解決機能が強力です。 ドキュメント には Pipenv で依存関係の解決に失敗する場合でも、Poetry では問題ないという例が書かれています。

パッケージの配布まで考慮するなら、Pipenv よりも Poetry が便利です。 ただし、どちらも比較的新しいプロジェクトなので、更新が多いです。 また、PyPI 上でメタデータを正しく宣言していないパッケージがあると、依存関係の解決に時間がかかり、インストールが遅くなります。 そのため、これらを急いで使い始める必要はないと、個人的には思っています。

使い方の簡単な紹介

ほぼ公式ドキュメントのまる写しですが、簡単に使い方を紹介します。

Poetry のインストール

macOS や Linux で curl が使える場合は以下を実行します。 python の部分は python3.6 など、メインで使っているインタープリタに適宜変更してください。

curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python

もちろん、url から get-poetry.py をダウンロードしてから実行しても構いません。

python get-poetry.py

Windows でもこれでインストールして使えるはずですが、私の環境では使えませんでした。 エンコーディングの問題な気がしますが調べられていません。

pip でもインストールできますが、Poetry 自体の依存パッケージがインストールされるので推奨されていません。

なお、Poetry が不要になったときは pip で削除しましょう。

python -m pip uninstall poetry

Poetry の更新

次のコマンドで Poetry が最新バージョンに更新されます。

poetry self:update

Tab 補完機能

bash, zsh, fish を使っている場合は Tab キーで補完候補を表示できるようになります。 例えば、fish では次を実行します。

poetry completions fish > ~/.config/fish/completions/poetry.fish

new コマンド

プロジェクトの雛形を作成するコマンドです。

poetry new poetry-demo

作成されるディレクトリの構成は次のようになります。

poetry-demo
├── pyproject.toml
├── README.rst
├── poetry_demo
│   └── __init__.py
└── tests
    ├── __init__.py
    └── test_poetry_demo

pyproject.toml

pyproject.toml の項目は次のように指定します。 詳しくは ドキュメント を参照してください。

[tool.poetry.dependencies]
python = "^3.6"

[tool.poetry.dev-dependencies]
pytest = "^3.0"

dependencies に依存関係、dev-dependencies には開発のための依存関係を記述します。 また、"^3.6" のように、バージョンは制約条件で指定することもできます。 制約条件の指定方法は ドキュメント を参照してください。

なお、pyproject.lock には、実際に環境で使われるパッケージの情報が記述されます。 パッケージを追加、更新、削除すると、pyproject.lock も自動的に更新されます。

init コマンド

プロジェクトに pyproject.toml がない場合に新規作成するためのコマンドです。 pyproject.toml の項目を対話的に入力していくことができます。 なお、 --dependency オプションなどで項目を直接指定することもできます。

poetry init

仮想環境

Poetry は installadd コマンドなどが実行されると、まずはディレクトリに仮想環境があるかをチェックします。 仮想環境がなければ、自動で ~/.cache/pypoetry/virtualenvs などに仮想環境を作成します。 そのため、プロジェクトごとに必ず環境は分離されます。 使うインタープリタのバージョンを指定したい場合は、venv などで仮想環境を作成しておきましょう。

python3.6 -m venv .venv

install コマンド

プロジェクトの pyproject.toml を読み込み、依存関係を解決してインストールするコマンドです。

poetry install

オプション:

  • --no-dev: 開発用のパッケージはインストールしない
  • --extras (-E): 追加でインストールしたいパッケージを指定

update コマンド

環境にインストールされているパッケージを最新バージョンに更新するコマンドです。

poetry update

更新するパッケージを指定することもできます。

poetry update requests toml

オプション:

  • --dry-run: 実行はせず、どんな処理がされるかだけ表示

add コマンド

必要なパッケージを pyproject.toml に追加し、インストールするコマンドです。 バージョンの制約の指定がなければ、依存関係を解決して適切なバージョンが選択されます。

poetry add requests pendulum

オプション:

  • --dev (-D): 開発用の依存パッケージとして追加
  • --git: Git リポジトリの URL を指定
  • --path: 依存パッケージへのパスを追加
  • --extras (-E): 依存パッケージを有効にするための追加パッケージ
  • --optional: オプションの依存パッケージとして追加
  • --dry-run: 実行はせず、どんな処理がされるかだけ表示

remove コマンド

環境にインストールされているパッケージを削除するコマンドです。

poetry remove pendulum

オプション:

  • --dev (-D): 開発用の依存パッケージから削除
  • --dry-run: 実行はせず、どんな処理がされるかだけ表示

show コマンド

利用可能なパッケージの一覧を表示します。

poetry show

特定のパッケージの詳細を表示することもできます。

poetry show pendulum

オプション:

  • --tree: ツリー構造で依存関係を表示
  • --latest (-l): 最新バージョンを表示
  • --outdated (-o): バージョンの古いパッケージだけ表示

build コマンド

ソースコード配布物 (sdist、wheel のアーカイブ) を作成するコマンドです。 現時点では、pure python なパッケージだけ使えます。

poetry build

オプション:

  • --format (-f): 形式を sdist か wheel だけに限定

publish コマンド

build コマンドでビルドしたパッケージをリモートリポジトリに発行します。 初めての場合は、アップロードする前にパッケージを自動的に登録します。

poetry publish

オプション:

  • --build: パッケージをビルドする
  • --repository (-r): パッケージを登録するリポジトリ (デフォルト: pypi)。 config コマンドで設定したリポジトリ名と一致する必要があります。
  • --username (-u): リポジトリにアクセスするユーザー名
  • --password (-p): リポジトリにアクセスするパスワード

config コマンド

リポジトリなどの設定を編集するコマンドです。 例えば、新しく foo というリポジトリの url と認証情報を設定するには、次のように実行します。

poetry config repositories.foo https://foo.bar/simple/
poetry config http-basic.foo username password

なお、PyPI の認証情報も同じように設定しておけます。

オプション:

  • --unset: 指定の設定変数の値を削除
  • --list: 現在の設定変数のリストを表示

これで設定した foo リポジトリに発行できるようになります。

poetry publish -r foo

また、このリポジトリからも依存パッケージをインストールできるようにするには、pyproject.toml に次のように設定しておきます。

[[tool.poetry.source]]
name = "foo"
url = "https://foo.bar/simple/"

run コマンド

プロジェクトの仮想環境内でコマンドを実行します。 仮想環境を有効化する作業は不要です。

poetry run python -V

また、pyproject.toml で次のようにスクリプトを定義しておくと、

[tool.poetry.scripts]
my-script = "my_module:main"

それを直接実行することもできます。

poetry run my-script

check コマンド

pyproject.toml の構造を検証し、エラーがあるか詳細なレポートを返します。

poetry check

search コマンド

リポジトリのインデックスからパッケージを検索します。

poetry search requests pendulum

lock コマンド

pyproject.toml で指定された依存パッケージをインストールせずに pyproject.lock を更新します。

poetry lock

Pipenv は公式で推奨されるツールの一つでしかない

"the officially recommended Python packaging tool from Python.org, free (as in freedom)"

これは Pipenv のドキュメントのトップに書かれていた文です。 現在でもドキュメントの PDF 版や、PyPI のページにはこの文が残っています。 "the" と付いていたため、唯一推奨するというニュアンスになっていました。 しかし、Pipenv は結局 requirements.txt を置き換えるだけでしかありません。 Pipfile の仕様も PEP で決まったものでもなく、この文については反対の声がありました。 そして、Poetry が登場したことで、reddit で Pipenv が PyPA で唯一推奨するツールなのかと盛り上がりました。 その内容に興味があれば下のリンクを参照してください。 結局、PyPA に公式ツールというものはなく、Pipenv も特定のユースケースで推奨できるツールの一つでしかないとなりました。 そして、Pipenv のドキュメントから上記の文はなくなりました。 現在は PyPA のドキュメントでも、Pipenv のほか、pip-tools、flit、hatch、Poetry などをユースケースに合わせて選択するように書かれています。

参考:

まとめ

  • Pipenv は PyPA が推奨するツールの一つ
  • パッケージの配布まで考慮する場合は Poetry をチェックしてみよう
電子書籍