pipの待ち時間とPython環境の迷宮からの解放
CI/CDランナー上で pip install -r requirements.txt の完了をひたすら待たされた経験は誰にでもあるはずです。依存関係の解決(dependency resolution)に5〜10分もかかるのは日常茶飯事でした。また、開発マシンの移行も骨の折れる作業です。ローカルにはPython 3.10があるのにプロジェクト要件は3.12である場合、pyenv を再設定し、手動で venv を作成し、Poetryのライブラリ競合解決をもどかしく待つことになります。
このボトルネックは、ツールの根本的な設計に起因しています。Pythonエコシステムの従来ツールの多くはPython自身で記述されています。そのため依存グラフが肥大化すると、バックトラッキングアルゴリズムとシングルスレッドI/Oが深刻なパフォーマンス低下を引き起こします。さらに、各プロジェクトがライブラリを個別に複製して保持するため、気づけば30〜40GBものSSD容量が静かに消費されていました。
そんな中、超高速リンター「Ruff」を手がけるAstralが2024年初頭に発表したのがuvです。100% Rustで開発されたuvは、pipやPoetryと比較して10〜100倍という圧倒的なパッケージ解決速度を誇ります。Pythonランタイムのダウンロードから仮想環境管理、依存関係のロックまでを網羅し、煩雑だったツールチェーンを単一のバイナリへと集約します。
1. クイックスタート:5分で体験するuv
複雑な初期設定は一切不要です。わずか数コマンドで、その驚異的な処理速度を実感できます。
ステップ1:uvのインストール
LinuxおよびmacOS環境では、ターミナルで以下のコマンドを実行します。
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows(PowerShell)環境の場合:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
インストールが正常に完了したか確認します。
uv --version
ステップ2:プロジェクトの初期化と最初のスクリプト実行
# ディレクトリを作成し、pyproject.toml標準に準拠したプロジェクトを初期化
mkdir demo-uv && cd demo-uv
uv init
# ライブラリの追加:仮想環境が存在しない場合はuvが自動生成
uv add requests pydantic
# venvを手動アクティベートすることなく直接ファイルを実行
uv run hello.py
ローカルキャッシュが存在する場合、パッケージのダウンロードとリンク処理にかかる時間はわずか0.2〜0.5秒程度です。従来のpipとは一線を画す、瞬時に完了する快適さを体感できます。
2. 詳細解説:uvはpip、venv、Poetryをどう置き換えるのか?
2.1. pipの完全互換(ドロップイン代替)
既存のプロジェクト構成を崩したくない場合は、uv pip サブコマンドが役立ちます。pipと同一の構文を保ちつつ、桁違いの高速処理を実現します。
# 1〜2秒かかっていた仮想環境の作成をわずか15〜30msで完了
uv venv
# 仮想環境のアクティベート(Linux/macOS)
source .venv/bin/activate
# Rustの高速処理でrequirementsファイルをインストール
uv pip install -r requirements.txt
# パッケージリストを正確に出力
uv pip freeze > requirements.txt
2.2. Pythonバージョンの自動ダウンロードと固定
もう pyenv を別途管理する必要はありません。uvは信頼性の高いスタンドアロンビルドから直接、指定バージョンのPythonを自動取得します。
# 複数のPythonバージョンを並列かつ数秒でインストール
uv python install 3.11 3.12
# システム上で検出された全Pythonバージョンを一覧表示
uv python list
# .python-versionファイルを通じてプロジェクトで使用するバージョンを固定
uv python pin 3.12
2.3. Poetryに代わる包括的なプロジェクト管理
uvはPEP 621に完全準拠した pyproject.toml を採用しており、マルチプラットフォーム(Windows、Linux、macOSで一貫して動作)対応の uv.lock を生成します。
# メインアプリケーション向けパッケージの追加
uv add fastapi uvicorn
# 開発・テスト環境向けの依存パッケージを分離して追加
uv add --dev pytest ruff
# 指定パッケージと不要になった関連サブ依存をきれいに削除
uv remove requests
# uv.lockに基づいて環境を完全同期(CI/CDパイプラインに最適)
uv sync
3. 応用機能:単一スクリプトの実行とCLIツール活用
3.1. インラインメタデータ(PEP 723)による単一スクリプトの実行
ちょっとした自動化スクリプトを実行するためだけに仮想環境を丸ごと立ち上げる必要はありません。ファイルの先頭に依存関係を直接宣言できます。
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "httpx",
# "rich",
# ]
# ///
import httpx
from rich import print
resp = httpx.get("https://api.github.com/repos/astral-sh/uv")
print(resp.json())
実行は以下のコマンド1つで完結します。
uv run script.py
uvが一時的な隔離環境を自動生成して httpx と rich を取得・実行し、終了後は自動でクリーンアップします。ローカルマシンのグローバル環境は一切汚れません。
3.2. グローバルインストール不要のCLIツール高速実行(npxライクな利用)
uvx(uv tool run の短縮形)を使用すれば、PythonベースのあらゆるCLIツールを手軽にワンショット実行できます。
# マシンにruffをインストールすることなくコードを自動フォーマット
uvx ruff format .
# HTTPieを使って手軽にAPIエンドポイントを検証
uvx httpie https://httpbin.org/get
4. 実務で役立つuv運用のプラクティス
- グローバルキャッシュの有効活用: uvは同一ディスクパーティション上でハードリンクを活用します。10個のプロジェクトでそれぞれ
torchやpandasを利用していても、実データとして消費されるディスク容量は1回分のみです。不要になった古いビルドキャッシュはuv cache pruneで安全に解放できます。 - Dockerビルド時間を最大80%短縮: マルチステージビルドを活用して
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uvでバイナリを配置し、uv sync --frozen --no-install-projectを実行します。これにより、CI上のコンテナイメージビルド時間を3〜4分から25秒未満へと大幅に短縮可能です。 - スクリプト組み込み前の正規表現テスト: ログ解析スクリプトなどを書く際、正規表現内のバックスラッシュ(
\)のエスケープ不備によるエラーが発生しがちです。ターミナルでの試行錯誤を繰り返す前に、toolcraft.app/ja/tools/developer/regex-tester のようなWebツールで事前にマッチングを検証しておくと手戻りを防げます。正しくキャプチャできることを確認した正規表現をPythonスクリプトへ組み込み、uv runで実行するのがスムーズです。 - Gitフックによる環境統一: uvと
pre-commitを組み合わせることで、チーム内の全エンジニアが同一バージョンのリンターを実行する環境を担保でき、「ローカル環境では動いていた」というありがちなトラブルを根本から排除できます。
uvへの移行メリットは、単にパッケージインストールの待ち時間を数十秒削るだけにとどまりません。ローカル開発からCI/CDパイプラインに至るPythonワークフロー全体を標準化し、堅牢でストレスのない開発体験をもたらしてくれます。
