uv で Python プロジェクトを依存ロック付きで再現可能にする
uv は Astral(Ruff の開発元)が作る Rust 製の Python パッケージ/プロジェクト管理ツールだ。pip + venv + pip-tools + pyenv あたりの役割を 1 バイナリにまとめ、依存解決が速いこと、そして uv.lock によるクロスプラットフォームな再現可能インストールが扱いやすいことで広く使われるようになった。
この記事では、プロジェクトを作って依存を追加し、uv.lock で別環境でも同じ状態を再現するところまでを、実際のコマンドと出力で確認する。本記事のコマンドは uv 0.4 以降で共通なので、まず uv --version で入っていることを確かめてほしい。
インストールと確認
未導入なら公式のインストーラを使う(macOS / Linux)。
1 | |
導入済みかどうかはバージョン表示で確認する。
1 | |
uv 本体は単一バイナリで、Python 自体が入っていなくても uv が必要な Python を用意できる(後述)。
プロジェクトを初期化する
uv init で新しいプロジェクトを作る。pyproject.toml と .python-version、サンプルスクリプトが生成される。
1 | |
生成された pyproject.toml にはプロジェクト名と対応 Python バージョン、依存配列(最初は空)が入っている。
依存を追加すると uv.lock が生まれる
uv add で依存を追加する。ここで仮想環境 .venv の作成、依存解決、pyproject.toml への追記、そして uv.lock の生成までが一度に行われる。
1 | |
追加後、ロックファイルが出来ていることを確認する。
1 | |
uv.lock には依存の完全な解決結果(バージョンとハッシュ、プラットフォーム条件)が記録される。これがコミット対象で、再現性の核になる。.venv はコミットしない。
スクリプトを動かす
追加した依存を使うスクリプトを用意する。main.py を次の内容で上書きする。
1 | |
uv run は「ロックと同期してから、その環境でコマンドを実行する」ため、事前の activate は要らない。
1 | |
uv run は実行のたびに uv.lock と .venv の同期を確認するので、「ロックを更新したのに入れ忘れて古い依存で動く」という事故が起きにくい。
別環境で同じ状態を再現する
ここが本題だ。uv.lock と pyproject.toml をコミットしておけば、別マシンや CI では uv sync だけでまったく同じ依存構成を作れる。ロックを一切変更させたくない場合は --frozen を付ける。
1 | |
ロック自体を明示的に作り直したいときは uv lock を単体で実行する。依存の更新は uv lock --upgrade(あるいは特定パッケージだけ uv lock --upgrade-package requests)で行い、差分は uv.lock にだけ現れる。
1 | |
「アプリのコードは変えず依存だけ上げた」がロックファイルの diff として明確に残るので、レビューしやすい。
Python 本体も uv が用意する
対応する Python が無ければ uv が取得・固定できる。プロジェクトの Python を 3.12 に固定する例。
1 | |
これで .python-version が更新され、以降の uv run / uv sync はその Python を使う。pyenv を別途入れなくても、プロジェクトごとの Python バージョン固定ができる。
使い捨てのツール実行: uvx
Lint やフォーマッタのような「プロジェクトの依存にはしたくないが手元で動かしたいツール」は uvx(uv tool run の短縮形)で一時環境から実行できる。インストールせずに ruff を走らせる例。
1 | |
uvx <tool> はツールを隔離した一時環境で実行するので、プロジェクトの pyproject.toml や uv.lock を汚さない。
まとめ
uv は「初期化(uv init)→依存追加(uv add)→実行(uv run)→別環境で再現(uv sync --frozen)」という流れを、uv.lock を軸に一貫して扱えるのが強みだ。コミットするのは pyproject.toml と uv.lock、実行時は activate 不要、Python 本体も uv が用意できる。手元に uv があれば、上の try-uv の手順をそのままなぞって uv run main.py まで試してほしい。依存を上げたときに uv.lock だけが変わる感覚がつかめるはずだ。