Open4

Pythonのパッケージ管理を支えるツールのまとめ(2024年版)

diiadiia

以下は各ツール/ライブラリの機能を比較した表。

name owner description install package lock dependency create venv build frontend build backend publish package task runner support inline metadata script manage cli tool manage python interpreter
setuptools pypa パッケージをビルドに使用されるライブラリ
venv python 仮想環境を作成するpythonの組み込みライブラリ 🔺{手動}
virtualenvs pypa 仮想環境を作成するCLIツール
venvのスーパーセット
🔺{手動}
pip pypa パッケージをインストールするCLIツール
pip-tools jazzband 依存関係のロック、ロックファイルからパッケージをインストールするCLIツール
(pip)
🔺
twine pypa ビルドしたパッケージをインデックスにアップロードするCLIツール
build pypa パッケージをビルドするCLIツール
pipx pypa CLIツール(awscli...)、PEP 723準拠のスクリプトを専用の仮想環境で(管理し)実行するCLIツール
(pip)
pyenv pyenv cpythonのビルド、インストール、管理を行うCLIツール 🔺
flit pypa パッケージのインストール、ビルド、配布が可能なCLIツール
(pip)
pipenv pypa 複数のツールを集約しパッケージ開発を簡素化するCLIツール
別途説明

(pip)
🔺 🔺{自動}
(virtualenvs)
poetry python-poetry 上に同じ 🔺{自動}
(virtualenvs)
pdm pdm-project 上に同じ
(virtualenvs)

hatch pypa 上に同じ
(uv)
🔺{自動}
(virtualenvs)

rye astral-sh 上に同じ
(uv)

(uv)
🔺{自動}
(virtualenvs)

(build)

(twine)
uv astral-sh 上に同じ

()はそのツールをラップして使用している事を指す。

diiadiia

install package

指定されたパッケージをpython環境にインストールする機能のこと。

lock dependency

使用するパッケージを依存解決し、どのバージョンをインストールする必要があるか、正確に指定するロックファイルを生成する機能のこと。
再現性の確保が必要なケースえは必須の機能。
ロックファイルは以下の2つに大別される。

  1. シングルプラットフォームのロックファイル
    • 実行環境(OS、pythonバージョン...)に固有のロックファイルのこと
    • 環境が変わると元のpython環境を再現できない
  2. クロスプラットフォームのロックファイル
    • 複数環境で(ほぼ)同一の環境を再現できるロックファイルのこと
表中の記号の説明
  • ⭕: クロスプラットフォームのロックファイルを生成
  • 🔺: シングルプラットフォームのロックファイルを生成
参考

create venv

Pythonの仮想環境を作成する機能のこと。
多くのツールが仮想環境の作成をサポートしているが、仮想環境の作成方法に差異がある。

  1. ユーザーが仮想環境を作成する
  2. ツールが仮想環境を作成する
    • 仮想環境が必要になったタイミングで、ツールが自動的に仮想環境を作成する
    • ユーザーは仮想環境を意識する必要がなく、仮想環境への操作はツールを介して行う

中には前述した両方をサポートしているツールも出てきている。

表中の記号の説明
  • ⭕: ユーザーが仮想環境を作成する、ツールが自動で仮想環境を作成するという2つの方式をサポート
  • 🔺: 何れか一方をサポート

build frontend

ビルドフロントエンドはPEP 517で導入された概念で、ソースツリーを入力とし、sdistやbdistへビルドするためのユーザーインタフェース、それを提供するツールを指す。
例えば、poetrypoetry buildでビルドフロントエンドのユーザーインタフェースを提供している。

実際のビルド処理は後述するビルドバックエンドに委任され、基本的にユーザーがバックエンドを自由に選択できる。ただし、ツールによっては専用のビルドバックエンドを使用する必要がある。

注釈

※1: 概ねpyproject.toml(setup.py,setup.cfg)とソースコードを含むディレクトリやその構造を指す。
※2: ソースコード配布物のこと。実行環境でのビルドを想定する配布型式の一種。
※3: ビルド配布物のこと。eggとwheelの型式があるが現在はwheelが主流。C/C++の拡張モジュールを含むパッケージの場合、実行環境のOS/CPUアーキテクチャ...の条件毎にビルドし配布するのが一般的。

表中の記号の説明
  • ⭕: ビルドフロントエンドエンドの機能を持ち、自由にバックエンドを選択できる
  • 🔺: ビルドフロントエンドエンドの機能を持つが、専用のバックエンドを使用する必要がある
参考

build backend

ビルドバックエンドはPEP 517で導入された概念で、ビルドフロントエンドの命令に基づきビルドを行う。
多機能なパッケージ管理ツールの一部は、ビルドバックエンドを抱き合わせで配布している。
例えば、poetryにおけるpoetry-corehatchにおけるhatchlingがこれに該当する。表ではこのケースも⭕とした。

publish package

ビルドされたパッケージ(sdist or bdist)をPyPI等のレジストリにアップロードする機能。

参考

task runner

開発時に使用するコマンドのエイリアスを作成し実行可能にする機能。
例えば、ruff check --fix .の様な長めのコマンドに対し、fmtというエイリアスを割当る等。

参考

support inline metadata script

inline metadata scriptはPEP 723で定義されているメタデータが、コメントとして埋め込まれたスクリプトのこと。以下はスクリプトの例。

# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])

この機能をサポートしているツールは、スクリプトの実行時に専用の仮想環境を作成し、そこに依存するパッケージをインストール、その中でスクリプトを動作させる。
そのため、スクリプトの実行のために手動で仮想環境を作成したり、依存関係をインストールする作業が不要となる。

参考

manage cli tool

CLIツールはターミナル上で使用するawscliruffを指す。
この機能をサポートするツールは、専用の仮想環境にCLIツールをインストールし、そのツールを仮想環境をアクティベート無しに実行可能にする。

参考

manage python interpreter

pythonのインタープリタを環境にインストールし、管理する機能で、インストールについては以下の2つのアプローチがある。

  1. ソースコードからpythonをビルドし、環境に導入する
  2. ビルド済みのpythonをダウンロードし、環境に導入する
記号の説明
  • ⭕: ビルド済みのpythonをダウンロード、インストールする
  • 🔺: ソースコードから(c)pythonをビルドし、インストールする
参考
diiadiia

pipenv

パッケージ開発のフローを簡素化するCLIツール。
2024年8月次点でpyproject.tomlに対応しておらずツールの中ではレガシー。
今から使用する価値はない。

パッケージのインストール

pipenv installで依存するパッケージを追加、環境にインストールする。

$ Creating a Pipfile for this project...
Installing numpy...
Resolving numpy...
Added numpy to Pipfile's [packages] ...
✔ Installation Succeeded
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (56f4dd913f06092b5800190ed38cbd47460bfb927fff151956e2efb228a6e810)!
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock (a6e810)...

この操作でPipfile(依存するパッケージ、Pythonバージョン等を記載した設定ファイル)とPipfile.lock(ロックファイル)をカレントディレクトリに生成、また既にあれば更新する。
この時、合わせて仮想環境も生成される。

$ ls
Pipfile         Pipfile.lock 

pipenv syncでロックファイルからパッケージをインストールする。
このコマンドは環境を再現する時に使用する。

$ pipenv sync
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock (a6e810)...
All dependencies are now up-to-date!
仮想環境の作成

仮想環境はツールが管理し、pipenv installでパッケージを導入するタイミングで仮想環境が自動的に作成される。

環境のアクティベートにはpipenv shellを使用する。

$ pipenv shell
Launching subshell in virtual environment...
 . /Users/xxx/.local/share/virtualenvs/test-jJqwcJEH/bin/activate                

pipenv runでは環境をアクティベートせずに、仮想環境中で任意のコマンドを実行できる。

$ pipenv run python -c "import numpy as np;print(np.version.version)"            2.1.1 

pipenvではvenvvirtualenvsの様に、ユーザーは仮想環境の生成、ディレクトリの管理をする必要はないが、仮想環境が隠蔽されるためVSCode等のエディタやIDEとの連携がし難い。
(仮想環境は~/.local以下に仮想環境生成され、ユーザー側から挙動を把握し難くい)

依存関係のロック

pipenvは依存解決した結果をロックファイル保持し、そこからパッケージをインストールすることで環境の再現性を担保している。
pipenv lockでロックファイルの生成、また生成済みのファイルを更新する。

$ pipenv 
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock (56f4dd913f06092b5800190ed38cbd47460bfb927fff151956e2efb228a6e810)!

pipenvが生成するロックファイルは、実行環境に依存するシングルプラットフォーム向けのもので、異なる環境では元のpython環境を再現できない。

diiadiia

poetry

pipenvの機能を順当に拡充したCLIツール。
pyproject.tomlを使用したモダンなパッケージ開発を最初に取り入れたツールだが、PEP 621の採択前にリリースされたため、pyproject.tomlに記載する依存関係やパッケージ名等のメタデータが独自の仕様になっており、他ツールへの移行や、ツール間の連携を困難にしている。

参考

パッケージのインストール

poetry installで開発対象のプロジェクトをインストールする。
依存するパッケージはロックファイルから
独自のインストーラーを採用、並列化により既存のツールと比較してパッケージのインストールが高速。

依存するパッケージの追加はpoetry add {パッケージ名}で行う。

また、パッケージ単位でソースとするインデックスを指定でき、torchの様にCPU、CUDA、ROCm版の様にバリアントが存在するパッケージでも、意図した通りに依存関係を指定できる。

参考

依存関係のロック

poetry lockで依存解決した結果をロックファイルに書き出す。
生成されるロックファイルはクロスプラットフォーム向けのもので、実行環境と異なるOS、CPUアーキテクチャでも環境を再現できる。
(試みを採用した最初のパッケージ管理ツール)

数年前までは、レゾルバが不安定でハングアップすることが多かったが、最近は安定してきている。

仮想環境の作成

基本的なスタンスはpipenvと同じ。
必要なタイミングでツールが仮想環境を作成し、その管理を行う。

パッケージのビルド(ビルドフロントエンド/バックエンド)

poetry buildでパッケージをビルドでき、ビルドフロントエンドの機能も持つ。

ただ、pyproject.tomlに記載するメタデータの仕様が独自であるため、専用のビルドバックエンドpoetry-coreを使用する必要があり、柔軟性に欠ける。

パッケージの配布

poetry publishでインデックスへのアップロードが可能。