uv (pythonパッケージマネージャー)の使い方 詳細版
Pythonのパッケージ管理はこれまで pip、venv、poetry などで行われてきましたが、最近 uv が注目を集めています。
本稿では uv をシステム開発で使うための詳細な情報、特に、poetry、venv、pipからの移行手順を解説します。
1. uvの概要
1.1 uvとは?
uvは 高速な動作、クロスプラットフォーム対応のロックファイル、ツール管理、Python自体のバージョン管理を統合した、現代的なPythonプロジェクト&パッケージマネージャーです。Rustで記述されており、従来のツール(pip, poetry, pip-toolsなど)の機能を単体で置き換えることができます。

1.2 uvのアーキテクチャ
uvはRustで実装されており、高いパフォーマンスとメモリ安全性を誇ります。Rustの並行処理能力を活用し、依存関係解決を高速化しています。また、効率的なキャッシュ機構を備えており、ダウンロードしたパッケージ、ビルドされたwheelファイル、ソースコードなどをキャッシュすることで、再利用性を高め、処理時間を短縮します。このキャッシュはスレッドセーフであり、複数のコマンドを同時実行しても安全に動作します。
1.3 uvのインストールとセットアップ
uvのインストールは、公式のスタンドアロンインストーラーを利用するのが最も簡単です。macOSとLinuxではcurlコマンド、WindowsではPowerShellコマンドを実行することで、最新版のuvをダウンロードしてインストールできます。
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
また、pip、Homebrew、Cargoといったパッケージマネージャーからもインストール可能です。
# pip
pip install uv
# Homebrew
brew install uv
# Cargo
cargo install --git https://github.com/astral-sh/uv uv
インストール後、uv generate-shell-completionコマンドを実行することで、シェルに自動補完機能を追加できます。
uvのアップグレードは、uv self updateコマンドで実行できます。アンインストールは、uv self uninstall、またはインストールディレクトリからバイナリを削除するだけで完了します。
2. uvの基本的な使い方
2.1 Pythonバージョンの管理
uvは、複数のPythonバージョンを管理することができます。uv python installコマンドで、任意のバージョンのPythonをインストールできます。
uv python install 3.11 3.12 3.13
uv python listコマンドで、インストール可能なバージョンやインストール済みのバージョンを確認できます。
uv python list
プロジェクトごとに使用するPythonバージョンを指定するには、.python-versionファイルにバージョン(例: 3.12)を記述するか、pyproject.toml に記述します。
uvは、コマンド実行時に必要なPythonバージョンが見つからない場合、自動的にダウンロードして使用します。
2.2 スクリプトの実行
uvは、スタンドアロンスクリプトの実行をサポートしています。uv runコマンドで、プロジェクト環境や一時的な環境でスクリプトを実行できます。
uv run example.py
スクリプトに必要な依存関係は、--withオプションで指定することで、一時的な仮想環境を作成して実行されます。
uv run --with requests example.py
また、スクリプトの先頭にインラインメタデータ(PEP 723)を記述することで、依存関係を自己完結的に宣言できます。
# /// script
# dependencies = ["requests"]
# ///
import requests
# ...
2.3 ツールの実行とインストール
uvは、Pythonパッケージが提供するコマンドラインツールの実行とインストールをサポートしています。uvxコマンド (またはuv tool run) で、インストールせずにツールを一時的に実行できます。
uvx ruff check
頻繁に使用するツールを永続的にインストールするには、uv tool installコマンドを使用します。これにより、ツールごとに隔離された環境が作られます。
uv tool install ruff
パッケージ名とコマンド名が異なる場合は、--fromオプションを使用します。
uvx --from httpie http
3. uvによるプロジェクト管理
3.1 プロジェクトの作成と初期化
uvは、標準仕様(PEP 621)に基づいた pyproject.toml によるプロジェクト管理をサポートしています。uv initコマンドで、新しいプロジェクトを作成できます。
uv init my-project
デフォルトではアプリケーションプロジェクト(--app相当)が作成されますが、--libオプションでライブラリプロジェクトを作成できます。
# アプリケーションプロジェクト(ロックファイルを生成し、環境を管理する)
uv init --app my-app
# ライブラリプロジェクト(配布用パッケージを作成する)
uv init --lib my-lib
uv initでは、hatchling、flit-core、setuptools、maturin といったビルドバックエンドを選択できます。--build-backendオプションで指定可能です。
uv init --lib --build-backend maturin my-lib
3.2 依存関係の管理
uv addコマンドで、pyproject.tomlの project.dependencies に依存関係を追加し、同時に仮想環境へインストールします。
uv add requests
--devオプションで、開発用の依存関係(dependency-groups または project.optional-dependencies)を追加できます。
uv add --dev pytest
uv removeコマンドで、依存関係を削除できます。
uv remove requests
3.3 環境の管理
uvは、プロジェクトルートに .venv という仮想環境を自動的に作成・管理します。uv syncコマンドで、uv.lock ファイルの内容に基づいて仮想環境を最新の状態に同期します。
uv sync
--frozenオプションをつけると、ロックファイルの更新を行わずに同期するため、CI/CD環境での利用に適しています。
--no-editableオプションで、自身のプロジェクトを編集不可モードでインストールできます。これは、Dockerコンテナの構築など、デプロイ時に便利です。
3.4 ロックファイルの管理
uvは、uv.lockというクロスプラットフォームのロックファイルを生成します。これはGit管理対象とすべきファイルです。
uv lockコマンドで、仮想環境を変更せずにロックファイルのみを更新できます。
uv lock --upgrade
3.5 ワークスペースの活用
uvは、Cargoスタイルのワークスペースをサポートしています。これにより、単一のリポジトリ(Monorepo)で複数のパッケージをまとめて管理できます。
pyproject.tomlにtool.uv.workspaceテーブルを追加することで、ワークスペースを作成できます。
[tool.uv.workspace]
members = ["packages/*"]
ワークスペースメンバー間では、tool.uv.sourcesを利用して相互依存を定義でき、uv sync 一発でワークスペース全体の環境を構築できます。
4. uvの高度な機能
4.1 依存関係の解決
uvは高度な依存関係解決アルゴリズムを備えており、以下の要素を考慮してすべての依存関係を満たす最適なパッケージの組み合わせを探索します。
- バージョン制約: 各パッケージに指定されたバージョン範囲
- プラットフォームマーカー: OS、アーキテクチャ、Pythonバージョンなどの条件
- 依存関係の競合: 異なるパッケージが同じ依存関係の異なるバージョンを要求する場合
uvは、ユニバーサル解決(デフォルト)を行い、Linux, macOS, Windowsなど全てのプラットフォームで動作する単一の uv.lock を生成します。これにより、チームメンバーのOSが異なっても同じ依存関係セットが保証されます。
4.2 キャッシュの管理
uvは、強力なグローバルキャッシュ機構を備えています。
uv cache cleanコマンドで、キャッシュをすべて削除できます。uv cache pruneコマンドで、未使用のキャッシュエントリを削除できます。CI環境などでキャッシュディレクトリを指定したい場合は UV_CACHE_DIR 環境変数が利用できます。
4.3 ビルドの分離
uvは、PEP 517とPEP 660に準拠したビルドの分離をサポートしています。各パッケージを隔離された環境でビルドすることで、依存関係の競合を防ぎます。
4.4 パブリッシュ
uvは、uv buildコマンドでPythonパッケージをソースディストリビューションとバイナリディストリビューションにビルドし、uv publishコマンドでPyPIなどのレジストリにアップロードすることができます。認証にはTrusted PublishingやAPIトークンが利用可能です。
5. uvと他ツールとの連携
5.1 Dockerとの連携
uvは、Dockerでの利用に最適化されています。公式Dockerイメージを利用することで、簡単にセットアップできます。
FROM python:3.12-slim
# 公式イメージからuvをコピー
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
# 依存関係ファイルのコピー
COPY pyproject.toml uv.lock ./
# 依存関係のインストール(システム環境に直接インストール)
RUN uv sync --frozen --no-cache
COPY . .
Dockerコンテナ内では仮想環境を作らず、システムPythonにインストールするのが一般的です。その場合、uv sync はデフォルトで .venv を作ろうとするため、環境変数 UV_PROJECT_ENVIRONMENT=/usr/local を設定するか、uv pip install --system コマンドなどを併用する手法があります。ただし、最新のベストプラクティスでは、RUN uv sync --frozen --no-install-project で依存関係のみをインストールする手法が推奨されます。
5.2 GitHub Actionsとの連携
GitHub Actionsでは、公式のastral-sh/setup-uvアクションを利用します。
steps:
- uses: actions/checkout@v7
- name: Install uv
uses: astral-sh/setup-uv@v10
with:
enable-cache: true
- name: Install dependencies
run: uv sync --frozen
- name: Run tests
run: uv run pytest
enable-cache: true を設定するだけで、キャッシュの保存・復元が自動的に行われ、ワークフローが高速化します。
5.3 GitLab CI/CDとの連携
GitLab CI/CDでも、公式Dockerイメージを利用できます。
variables:
UV_VERSION: 0.5
PYTHON_VERSION: 3.12
uv-job:
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_VERSION-bookworm-slim
script:
- uv sync --frozen
- uv run pytest
5.4 Jupyterとの連携
プロジェクト内でJupyterを使用するには、uv runコマンド経由で起動するのが確実です。
# JupyterLabを一時的に実行する場合
uvx --with jupyter jupyter lab
# プロジェクトの依存関係として追加済みの場合
uv run jupyter lab
既存のJupyter環境からuvの仮想環境をカーネルとして利用したい場合は、uv add --dev ipykernel した上でカーネルを登録します。
uv run python -m ipykernel install --user --name=my-project
5.5 pre-commitとの連携
uvは、pre-commitフックも提供しています。例えば、uv.lock が pyproject.toml と同期されているかをチェックしたり、requirements.txt を自動生成したりできます。
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.12.5
hooks:
# uv.lockが最新かチェックする
- id: uv-lock
# (オプション) requirements.txtを自動エクスポートする場合
- id: uv-export
args: ["--format", "requirements-txt", "--output-file", "requirements.txt"]
6. poetry, venv, pipからの移行
現在他のツールを使用しているチームが、uvのプロジェクト管理機能(uv sync / uv run)へ移行する手順は以下の通りです。
6.1 poetryからの移行
Poetryは独自の [tool.poetry] 設定を使用しますが、uvは標準のPEP 621 [project] 設定を使用します。
-
pyproject.tomlの書き換え: Poetry形式の記述を、標準的な
[project]テーブルに書き換えます。依存関係はtool.poetry.dependenciesからproject.dependenciesに移動します。- ※ 手動での書き換えが基本ですが、一度
requirements.txtを吐き出してから取り込む方法も簡便です。
- ※ 手動での書き換えが基本ですが、一度
-
依存関係の取り込み:
# Poetryで依存関係を出力 poetry export -f requirements.txt --output requirements.txt --without-hashes # uvプロジェクトの初期化 uv init # requirements.txtから依存関係を一括追加 uv add -r requirements.txt # 開発用依存関係も同様に poetry export --only dev -f requirements.txt --output dev-requirements.txt uv add --dev -r dev-requirements.txt -
クリーンアップ: 不要になった
poetry.lockやrequirements.txtを削除し、生成されたuv.lockをコミットします。
6.2 venv, pipからの移行
-
依存関係のエクスポート: 既存環境から依存リストを出力します。(もし既に手書きの
pip freeze > requirements.txtrequirements.txtがある場合はそれを使用します) -
uvプロジェクトの作成:
uv init -
依存関係の移行:これにより、
uv add -r requirements.txtrequirements.txtの内容がpyproject.tomlに転記され、uv.lockが生成されます。今後はrequirements.txtを直接編集するのではなく、uv add/uv removeで管理します。
7. uvのメリットとデメリット
メリット:
- 圧倒的なパフォーマンス: Rustによる実装により依存関係解決とインストールが非常に高速です。
- All-in-One: Pythonインストール、パッケージ管理、プロジェクト管理、ツール実行がこれ1つで完結します。
-
標準準拠: 独自のメタデータ形式ではなく、標準のPEP 621 (
pyproject.toml) を採用しています。 - クロスプラットフォーム: Windows, Mac, Linuxで一貫したロックファイルを使用できます。
デメリット:
- エコシステムの成熟度: 急速に開発が進んでいるため、破壊的な変更が入ることが稀にありますが、v0.5以降はかなり安定しています。
- 一部のビルドツールとの相性: 非常に特殊なビルド設定を持つ古いパッケージの場合、設定が必要なことがあります。
Discussion