最近Python のプロジェクト管理ツールである uv
を使い始めました。
そのサブコマンドは一見シンプルに見えますが、似たような機能に見えるコマンドがあるため
「どのコマンドを使えばいいの?」と戸惑うことがあります。
これは、 uv
のサブコマンドに「低レベルの機能」と「高レベルのラッパー」が混在しているためです。
この記事では、 uv
のサブコマンドを低レベルの機能と高レベルのラッパーに分類し、それぞれの役割や使いどころを整理してみます。特に、普段遣いで便利な高レベルのラッパーに注目し、効率的な使い方を解説します。
uv のサブコマンドを分類する
uv
のサブコマンドは、以下のように分類できます。
低レベルの機能
これらのコマンドは特定のタスクを直接実行するための基本的な操作を提供します。
uv pip
: パッケージのインストールやアンインストールを行う。uv venv
: 仮想環境の作成や管理を行う。uv python
: Python のバージョン管理やインストールを行う。uv cache
: キャッシュの管理を行う。uv self
:uv
自身のアップデートや管理を行う。
高レベルのラッパー
これらのコマンドは、低レベルの機能を組み合わせて、ユーザーが簡単に操作できるように設計されています。
uv add
: パッケージをインストールし、pyproject.toml
に追加。uv remove
: パッケージをアンインストールし、pyproject.toml
から削除。uv sync
:pyproject.toml
に基づいて依存関係をインストールし、環境を同期。uv lock
: 依存関係のバージョンを固定するロックファイルを生成または更新。uv run
: 仮想環境を意識せずにスクリプトやコマンドを実行。uv tool
: プロジェクトで使用するツールの管理。
高レベルのラッパーを使うと便利な理由
低レベルのコマンドを使えば、細かな操作を自由に行うことができます。しかし、普段遣いでは高レベルのラッパーを使う方が便利です。その理由を具体例とともに見ていきましょう。
例 1: パッケージのインストール
低レベルの方法:
uv pip install requests
# 依存関係を手動で pyproject.toml に記載
高レベルのラッパー:
uv add requests
ポイント: uv add
を使うと、パッケージのインストールと pyproject.toml
の更新が一度に行えます。
例 2: 依存関係の同期
低レベルの方法:
uv pip install -r requirements.txt
高レベルのラッパー:
uv sync
ポイント: uv sync
は pyproject.toml
に基づいて環境全体を同期するので、手動で requirements.txt
を扱う必要がありません。
例 3: 仮想環境の初期化
低レベルの方法:
uv venv create
# 必要ならば手動で環境を有効化 または
python -m venv .venv
高レベルのラッパー:
uv init
ポイント: uv init
は仮想環境の作成と初期化を一度に行い、プロジェクトをすぐに開始できる状態にします。
uv と pyenv の関係
uv
は Python のバージョン管理に関する機能も備えていますが、 pyenv
のような専用ツールと比較した場合、どのような関係になるのでしょうか?以下にその特徴を整理します。
uv
の Python バージョン管理機能
uv python pin
でプロジェクトに特定の Python バージョンを固定可能。uv python install
で特定の Python バージョンをインストール可能。uv python list
で利用可能な Python バージョンを一覧表示。
メリット:
- プロジェクトごとにバージョンを固定できるため、チーム開発でのバージョンの不一致を防ぎやすい。
pyproject.toml
にバージョン情報を記録することで、他の依存関係と統一的に管理可能。
制限:
- Python のインストールや管理のための操作は基本的にローカルに限定されているため、
pyenv
のようにシステム全体でのバージョン管理が目的ではない。
pyenv
の特徴
- システム全体、ユーザー単位、ディレクトリ単位で Python バージョンを切り替え可能。
- インストールできる Python バージョンの種類が豊富(公式バージョン、開発中のバージョン、PyPy、Stackless など)。
- 他のツール(
pipenv
、poetry
など)と組み合わせることで柔軟な運用が可能。
メリット:
- システム全体での Python バージョンの管理が容易。
- 複数のプロジェクトで異なるバージョンを使用する場合に便利。
制限:
- プロジェクトごとの依存関係管理との統合が弱く、別途ツールが必要になることが多い。
uv
が pyenv
を不要にするケース
- プロジェクトごとに特定の Python バージョンを固定し、チーム全体で同じ設定を共有することが主な目的の場合。
- Python のインストールやバージョン管理を
uv
に一任し、プロジェクト管理ツールとしての一貫性を重視する場合。
pyenv
が必要なケース
- システム全体や複数のプロジェクトで異なる Python バージョンを頻繁に切り替える場合。
- 特定の公式リリース外の Python バージョン(例: PyPy)の利用が必要な場合。
- 既存の開発環境で
pyenv
を中心にツールチェーンが構築されている場合。
高レベルラッパーと低レベル機能の関係
以下の表は、低レベルの機能とそれを置き換える高レベルのラッパーをまとめたものです。
低レベルコマンド | 高レベルラッパー | 説明 |
---|---|---|
uv pip install パッケージ名 | uv add パッケージ名 | パッケージのインストールと設定ファイルの更新を一度に実行。 |
uv pip uninstall パッケージ名 | uv remove パッケージ名 | パッケージのアンインストールと設定ファイルの更新を一度に実行。 |
uv pip install -r requirements.txt | uv sync | pyproject.toml に基づき環境を同期。 |
uv pip freeze > requirements.txt | uv lock | 依存関係のバージョン固定を簡単に実現。 |
source .venv/bin/activate python script.py | uv run python script.py | 仮想環境を意識せずにスクリプトを実行。 |
uv venv create | uv init | プロジェクトの初期化と仮想環境の作成を一度に実行。 |
pyenv install バージョン | uv python install バージョン | 特定の Python バージョンをインストール。 |
pyenv local バージョン | uv python pin バージョン | プロジェクト単位で Python バージョンを固定。 |
uv
の高レベルラッパーは、Python プロジェクトの管理をシンプルかつ効率的にしてくれる便利な機能です。一方で、低レベルの機能を直接使用することで、より細かな制御も可能です。低レベルの機能を利用したあとに pyproject.toml
を手動で更新している様な作業は、高レベルのラッパーの利用で一元化できる可能性があります。用途や目的に応じて高レベルラッパーと低レベル機能を使い分けることで、 uv
の真価を最大限に引き出しましょう。