Python uv パッケージマネージャー 2026:pip より 10 倍高速な依存関係管理ガイド
Python 依存関係管理の暗黒時代
すべての Python 開発者がこうした苦痛を経験している:
- pip のインストールが遅すぎる:Django プロジェクトの
pip installは数分かかり、依存関係の解決がCollectingステージで止まってイライラする - poetry の設定が難解:
pyproject.tomlの依存関係グループ、extras、source 設定が頭を悩ませ、lock ファイルの衝突は日常茶飯事 - venv の手動管理が煩雑:
python -m venv .venv、source .venv/bin/activate、deactivate……各プロジェクトでこの手順を繰り返す - Python バージョンの切り替えが混乱:pyenv、conda、システム Python が衝突し、
which pythonがどこを指しているかわからない - 依存関係のロックが信頼できない:
requirements.txtにはロックファイルがなく、pip freeze > requirements.txtで生成される依存関係には間接依存が含まれ、環境を再現できない
2024 年、Astral チーム(ruff の開発元)が uv をリリースした——Rust で書かれた Python パッケージマネージャーで、pip より 10-100 倍高速。2026 年までに、uv は Python エコシステムで最も注目されるパッケージ管理ツールとなり、プロジェクト管理、仮想環境、Python バージョン管理、Monorepo ワークスペースなどフルスタック機能をサポートしている。
本記事では、コアコンセプトから始め、5 つの実践パターンを通じて uv の使い方を完全にマスターする。
コアコンセプトリファレンス
| コンセプト | 説明 | 対応コマンド |
|---|---|---|
| プロジェクト管理 | プロジェクトの初期化、依存関係の宣言管理 | uv init、uv add、uv remove |
| 仮想環境 | .venv の自動作成・管理 | uv venv、uv sync |
| Python バージョン管理 | Python インタープリタのインストールと切り替え | uv python install、uv python pin |
| 依存関係ロック | 再現可能なロックファイルの生成 | uv lock(uv.lock を自動生成) |
| 依存関係解決 | 高性能な依存ツリー解決 | 内蔵 Rust リゾルバ、10-100x 高速化 |
| ワークスペース | Monorepo マルチパッケージ管理 | uv workspace |
| ツール実行 | CLI ツールの一時インストールと実行 | uv tool run、uvx |
| スクリプト実行 | インライン依存関係宣言でスクリプトを実行 | uv run script.py |
| キャッシュ管理 | グローバルパッケージキャッシュ、重複ダウンロード回避 | uv cache |
| 依存関係エクスポート | requirements.txt 形式でエクスポート | uv export |
5 つのコアチャレンジ分析
チャレンジ 1:依存関係解決速度
pip はバックトラッキング解決アルゴリズムを使用し、複雑な依存グラフでは数分かかるか解決に失敗することもある。uv は SAT ソルバーベースの高性能リゾルバを採用し、通常ミリ秒単位で解決を完了する。
チャレンジ 2:環境の一貫性
requirements.txt には完全な依存関係ロック情報が含まれておらず、異なるマシンで異なる結果になる可能性がある。uv の uv.lock ロックファイルは完全な依存ツリーハッシュを記録し、どの環境でも正確に再現できる。
チャレンジ 3:Python バージョンの断片化
異なるプロジェクトが異なる Python バージョンを必要とし、pyenv + venv の組み合わせ設定は煩雑。uv は Python バージョン管理を内蔵し、1 つのコマンドでインストールと切り替えが可能、追加ツール不要。
チャレンジ 4:Monorepo 依存関係共有
複数のサブパッケージ間に内部依存関係があり、従来のアプローチではプライベート PyPI への手動公開や pip install -e が必要。uv ワークスペースは Monorepo をネイティブサポートし、サブパッケージ間を自動リンクする。
チャレンジ 5:CI/CD キャッシュ効率
pip は CI で毎回依存関係を再ダウンロードし、キャッシュがあってもキャッシュミスが頻発。uv のグローバルキャッシュ + コンテンツアドレス指定メカニズムにより、CI キャッシュヒット率がほぼ 100% に。
パターン 1:uv のインストールとプロジェクト初期化
uv のインストール
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# pip でインストール(非推奨、フォールバックのみ)
pip install uv
# Homebrew を使用
brew install uv
# インストールの確認
uv --version
# uv 0.7.12 (2026 年最新安定版)
プロジェクト初期化
# 新しいプロジェクトを作成
uv init my-project
cd my-project
# プロジェクト構造
# my-project/
# ├── .python-version # Python バージョンの固定
# ├── pyproject.toml # プロジェクト設定と依存関係宣言
# ├── uv.lock # 依存関係ロックファイル(自動生成)
# ├── hello.py # サンプルエントリファイル
# └── .venv/ # 仮想環境(自動作成)
依存関係管理
# 依存関係を追加
uv add fastapi
uv add "sqlalchemy>=2.0"
uv add --dev pytest
uv add --dev ruff
# オプション依存関係グループを追加
uv add --optional ml torch
# 依存関係を削除
uv remove pytest
# 依存関係を同期(pyproject.toml で宣言されたすべてをインストール)
uv sync
# 本番依存関係のみ同期(dev を除外)
uv sync --no-dev
# 特定グループを同期
uv sync --group ml
pyproject.toml 構造
[project]
name = "my-project"
version = "0.1.0"
description = "A modern Python project"
requires-python = ">=3.12"
dependencies = [
"fastapi>=0.115.0",
"sqlalchemy>=2.0",
]
[project.optional-dependencies]
ml = [
"torch>=2.5",
"transformers>=4.45",
]
[tool.uv]
dev-dependencies = [
"pytest>=8.0",
"ruff>=0.8",
]
[tool.uv.sources]
my-private-pkg = { git = "https://github.com/myorg/my-private-pkg.git", tag = "v1.0.0" }
プロジェクトの実行
# 仮想環境でスクリプトを実行
uv run python hello.py
# モジュールを実行
uv run python -m my_project.main
# インライン依存関係宣言付きでスクリプトを実行
uv run --with requests python fetch_data.py
パターン 2:仮想環境と Python バージョン管理
仮想環境管理
# 仮想環境を作成(デフォルトは .venv ディレクトリ)
uv venv
# Python バージョンを指定して作成
uv venv --python 3.12
# 仮想環境のパスを指定
uv venv /path/to/.venv
# 仮想環境を有効化
# macOS / Linux
source .venv/bin/activate
# Windows
.venv\Scripts\activate
# uv sync は自動的に仮想環境を作成
uv sync
Python バージョン管理
# 利用可能な Python バージョンを表示
uv python list
# 特定の Python バージョンをインストール
uv python install 3.12
uv python install 3.13
# 特定の実装をインストール
uv python install pypy3.10
uv python install graalpy3.11
# プロジェクトの Python バージョンを固定(.python-version に書き込み)
uv python pin 3.12
# インストール済みバージョンを表示
uv python list --only-installed
# Python インタープリタのパスを検索
uv python find 3.12
# 特定バージョンを一時的に使用
uv run --python 3.13 python --version
.python-version ファイル
3.12
このファイルは uv によって自動的に読み取られ、チームメンバーが一貫した Python バージョンを使用することを保証する。uv sync と組み合わせることで、新規メンバーは clone 後 1 つのコマンドで完全な環境を構築できる。
マルチバージョン並行シナリオ
# プロジェクト A は Python 3.12 を使用
cd project-a
uv python pin 3.12
uv sync
# プロジェクト B は Python 3.13 を使用
cd project-b
uv python pin 3.13
uv sync
# 2 つのプロジェクトは互いに干渉せず、pyenv の切り替え不要
パターン 3:pip/requirements.txt と poetry/pyproject.toml からの移行
pip + requirements.txt からの移行
# 方法 1:既存のプロジェクトで初期化
cd existing-project
uv init
# uv は既存の requirements.txt を検出して自動インポート
# 方法 2:手動で依存関係をインポート
uv add $(cat requirements.txt | grep -v "^#" | grep -v "^$" | tr "\n" " ")
# 方法 3:uv pip 互換モードを使用(移行期間)
uv pip install -r requirements.txt
uv pip compile requirements.in -o requirements.txt
# requirements.txt 形式にエクスポート
uv export > requirements.txt
uv export --no-dev > requirements-prod.txt
poetry からの移行
# uv は poetry の pyproject.toml を直接読み取る
cd poetry-project
uv init
# uv は [tool.poetry.dependencies] を自動識別して移行
# 手動移行手順
# 1. poetry.lock をバックアップ
cp poetry.lock poetry.lock.bak
# 2. poetry の依存関係形式を PEP 621 形式に変換
# poetry 形式:
# [tool.poetry.dependencies]
# fastapi = "^0.115.0"
# PEP 621 形式:
# [project]
# dependencies = ["fastapi>=0.115.0"]
# 3. uv.lock を生成
uv lock
# 4. 依存関係を同期
uv sync
poetry から uv への pyproject.toml 変換スクリプト
import tomllib
import tomli_w
from pathlib import Path
def migrate_poetry_to_uv(pyproject_path: str = "pyproject.toml"):
""poetry 形式の pyproject.toml を uv 互換形式に変換""
path = Path(pyproject_path)
data = tomllib.loads(path.read_text(encoding="utf-8"))
poetry_deps = data.get("TOOL", {}).get("poetry", {}).get("dependencies", {})
poetry_dev_deps = (
data.get("TOOL", {})
.get("poetry", {})
.get("group", {})
.get("dev", {})
.get("dependencies", {})
)
def convert_version(version_spec: str) -> str:
if isinstance(version_spec, dict):
return version_spec.get("version", "*")
if version_spec.startswith("^"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{int(parts[0]) + 1}.0.0"
return f">={base},<{upper}"
if version_spec.startswith("~"):
base = version_spec[1:]
parts = base.split(".")
upper = f"{parts[0]}.{int(parts[1]) + 1}.0"
return f">={base},<{upper}"
return version_spec
dependencies = []
for name, version in poetry_deps.items():
if name == "python":
data.setdefault("project", {})["requires-python"] = f">={version}"
continue
dep = convert_version(version)
dependencies.append(f"{name}{dep}" if dep != "*" else name)
data.setdefault("project", {})["dependencies"] = dependencies
dev_dependencies = []
for name, version in poetry_dev_deps.items():
dep = convert_version(version)
dev_dependencies.append(f"{name}{dep}" if dep != "*" else name)
if dev_dependencies:
data.setdefault("TOOL", {}).setdefault("uv", {})[
"dev-dependencies"
] = dev_dependencies
if "poetry" in data.get("TOOL", {}):
del data["TOOL"]["poetry"]
path.write_text(tomli_w.dumps(data), encoding="utf-8")
print(f"移行完了: {dependencies=}, {dev_dependencies=}")
if __name__ == "__main__":
migrate_poetry_to_uv()
pipenv からの移行
# Pipfile の依存関係を requirements.txt にエクスポート
pipenv requirements > requirements.txt
# uv で初期化してインポート
uv init
uv add $(cat requirements.txt | tr "\n" " ")
uv sync
パターン 4:Monorepo とワークスペース管理
ワークスペース初期化
# Monorepo ルートディレクトリを作成
mkdir my-monorepo && cd my-monorepo
uv init --workspace
# サブパッケージを作成
uv init --package libs/core
uv init --package libs/api
uv init --package apps/web
# プロジェクト構造
# my-monorepo/
# ├── pyproject.toml # ワークスペースルート設定
# ├── uv.lock # グローバルロックファイル(統一管理)
# ├── libs/
# │ ├── core/
# │ │ ├── pyproject.toml
# │ │ └── src/core/
# │ └── api/
# │ ├── pyproject.toml
# │ └── src/api/
# └── apps/
# └── web/
# ├── pyproject.toml
# └── src/web/
ルート pyproject.toml 設定
[tool.uv.workspace]
members = [
"libs/core",
"libs/api",
"apps/web",
]
[tool.uv.sources]
core = { workspace = true }
api = { workspace = true }
サブパッケージ pyproject.toml
# libs/core/pyproject.toml
[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"pydantic>=2.9",
]
# libs/api/pyproject.toml
[project]
name = "api"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"fastapi>=0.115.0",
]
# apps/web/pyproject.toml
[project]
name = "web"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"core",
"api",
"uvicorn>=0.32.0",
]
ワークスペース操作
# ワークスペース全体を同期
uv sync
# 特定のサブパッケージのみ同期
uv sync --package api
# 特定のサブパッケージでコマンドを実行
uv run --package api python -m api.main
# 特定のサブパッケージに依存関係を追加
uv add --package api httpx
# 特定のサブパッケージをビルド
uv build --package core
# 特定のサブパッケージを公開
uv publish --package core
ワークスペース依存グラフ検証
# 依存ツリーを表示
uv tree
# 依存関係の衝突をチェック
uv lock --check
# 特定の依存関係を更新
uv lock --upgrade-package fastapi
パターン 5:CI/CD 統合と Docker 最適化
GitHub Actions 統合
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
enable-cache: true
cache-dependency-glob: "uv.lock"
- name: Set up Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --frozen
- name: Run linter
run: uv run ruff check .
- name: Run tests
run: uv run pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
GitLab CI 統合
# .gitlab-ci.yml
stages:
- test
- build
test:
stage: test
image: python:3.12-slim
before_script:
- pip install uv
- uv python install 3.12
- uv sync --frozen
script:
- uv run ruff check .
- uv run pytest --cov=src
cache:
key:
files:
- uv.lock
paths:
- .venv/
- ~/.cache/uv/
build:
stage: build
image: python:3.12-slim
before_script:
- pip install uv
script:
- uv build
artifacts:
paths:
- dist/
Docker マルチステージビルド最適化
# Dockerfile
FROM ghcr.io/astral-sh/uv:latest AS uv
FROM python:3.12-slim AS deps
COPY --from=uv /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-install-project --no-dev
FROM python:3.12-slim AS runtime
WORKDIR /app
COPY --from=deps /app/.venv /app/.venv
COPY . .
ENV PATH="/app/.venv/bin:$PATH"
ENV VIRTUAL_ENV="/app/.venv"
CMD ["python", "-m", "my_project.main"]
Docker Compose 開発環境
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- .:/app
- uv-cache:/root/.cache/uv
environment:
- PYTHONUNBUFFERED=1
command: uv run uvicorn my_project.main:app --host 0.0.0.0 --reload
volumes:
uv-cache:
CI キャッシュ最適化のヒント
# --frozen でロックファイルが変更されないことを保証(CI 環境では必須)
uv sync --frozen
# --no-dev でインストール量を削減
uv sync --frozen --no-dev
# オフラインインストール(依存関係がキャッシュされている場合)
uv sync --frozen --offline
よくある落とし穴ガイド
落とし穴 1:pip と uv の混用
❌ uv 管理のプロジェクトで pip install を使用し、uv の依存関係管理をバイパスする
✅ 常に uv add で依存関係を追加し、uv sync で環境を同期。一時的なインストールには uv pip install(互換モード)を使用
落とし穴 2:uv.lock のコミットを忘れる
❌ uv.lock を .gitignore に追加し、チームメンバー間で依存バージョンが不整合に
✅ uv.lock をバージョン管理にコミットし、すべての環境で同じ依存バージョンを使用。CI では --frozen を使用して意図しない更新を防止
落とし穴 3:Python バージョンの固定を忘れる
❌ .python-version を設定せず、開発者ごとに異なる Python バージョンを使用して互換性問題が発生
✅ uv python pin 3.12 でバージョンを固定し、.python-version をリポジトリにコミット
落とし穴 4:グローバルインストールの汚染
❌ uv tool install で多数のグローバルツールをインストールし、バージョン衝突のトラブルシューティングが困難に
✅ プロジェクトレベルのツールには uv run --with で一時インストールして実行。グローバルツールは高頻度使用のもののみ(ruff、black など)
落とし穴 5:Docker でキャッシュレイヤーを活用しない
❌ すべてのソースコードを COPY してから uv sync を実行し、コード変更のたびに依存関係を再インストール
✅ まず pyproject.toml + uv.lock を COPY し、uv sync を実行してからソースコードを COPY。Docker キャッシュレイヤーを活用して重複インストールを回避
エラートラブルシューティング表
| エラー | 考えられる原因 | 解決策 |
|---|---|---|
error: No virtual environment found |
仮想環境が作成されていない | uv sync または uv venv を実行して自動作成 |
error: Failed to download package |
ネットワーク問題または PyPI に到達できない | ミラーを設定:uv pip config set global.index-url https://pypi.org/simple |
error: Python 3.12 not found |
Python バージョンがインストールされていない | uv python install 3.12 を実行 |
error: Lockfile is out of date |
pyproject.toml が更新されたがロックされていない | uv lock を実行してロックファイルを更新 |
error: Resolution failed |
依存バージョンの衝突 | pyproject.toml のバージョン制約を確認、uv tree で依存ツリーを表示 |
error: Package not found in workspace |
ワークスペースメンバーの設定エラー | [tool.uv.workspace] の members パスを確認 |
uv sync が遅い |
キャッシュミスまたはネットワーク遅延 | キャッシュディレクトリの権限を確認、ミラーを設定、--offline モードを使用 |
error: Hash mismatch |
パッケージが改ざんされたかキャッシュが破損 | uv cache clean を実行してキャッシュをクリア後にリトライ |
error: Cannot activate venv |
仮想環境が破損 | .venv ディレクトリを削除して uv sync を再実行 |
error: Unsupported Python version |
Python バージョンが requires-python を満たしていない | uv python install を実行して要件を満たすバージョンをインストール |
高度な最適化のヒント
1. ミラーソースの高速化
# PyPI ミラーを設定
uv pip config set global.index-url https://pypi.org/simple
# または pyproject.toml で設定
# [tool.uv]
# index-url = "https://pypi.org/simple"
# マルチソース設定(プライベート PyPI + パブリック)
# [tool.uv]
# extra-index-url = ["https://pypi.mycompany.com/simple/"]
2. キャッシュ管理
# キャッシュ情報を表示
uv cache dir
uv cache list
# キャッシュをクリア
uv cache clean
# 特定パッケージのキャッシュをクリア
uv cache clean numpy
# キャッシュサイズを表示
du -sh $(uv cache dir)
3. オフライン環境デプロイ
# 依存関係を vendor ディレクトリにエクスポート
uv export --no-dev > requirements.txt
uv pip download -r requirements.txt -d vendor/
# オフラインインストール
uv pip install --no-index --find-links vendor/ -r requirements.txt
4. スクリプトインライン依存関係
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "requests>=2.32",
# "rich>=13.0",
# ]
# ///
import requests
from rich import print
response = requests.get("https://httpbin.org/json")
print(response.json())
# 直接実行、uv が依存関係を自動インストール
uv run script.py
5. 依存関係セキュリティ監査
# 既知の脆弱性をチェック
uv audit
ツール比較選定
| 項目 | uv | pip | poetry | pdm | conda |
|---|---|---|---|---|---|
| 依存関係解決速度 | 極速(Rust) | 遅い(バックトラッキング) | 中程度 | 速い | 遅い |
| 仮想環境管理 | 内蔵 | venv が必要 | 内蔵 | 内蔵 | 内蔵 |
| Python バージョン管理 | 内蔵 | pyenv が必要 | pyenv が必要 | 内蔵 | 内蔵 |
| ロックファイル | uv.lock | なし | poetry.lock | pdm.lock | なし |
| Monorepo サポート | ネイティブワークスペース | 非対応 | 非対応 | 限定 | 非対応 |
| CI キャッシュ親和性 | 極めて高い | 普通 | 高い | 高い | 低い |
| 設定の複雑さ | 低い | 低い | 高い | 中程度 | 高い |
| エコシステム成熟度 | 急成長中 | 最も成熟 | 成熟 | 成長中 | 成熟 |
| 学習曲線 | 緩やか | 緩やか | 急 | 中程度 | 急 |
| パッケージ数 | PyPI 全量 | PyPI 全量 | PyPI 全量 | PyPI 全量 | Anaconda + PyPI |
| 言語横断サポート | Python のみ | Python のみ | Python のみ | Python のみ | マルチ言語(C/C++/R) |
| 推奨度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
選定の推奨:
- 新規プロジェクト → uv(フルスタック機能、超高速体験)
- 既存の poetry プロジェクト → uv に段階的に移行(poetry 設定との互換読み取り)
- データサイエンス/ML プロジェクト → uv + conda の補完(uv は純粋な Python パッケージ、conda は C/C++ 依存関係を管理)
- シンプルなスクリプト/一回限りのタスク → uv run(プロジェクト初期化不要)
関連ツール
Python プロジェクト開発において、以下の ToolsKu ツールが役立ちます:
- JSON フォーマッター — API レスポンスや設定ファイルをフォーマット、pyproject.toml の JSON データ問題をデバッグ
- ハッシュ計算 — 依存パッケージのハッシュ値を計算、ダウンロードの完全性を検証
- cURL → コード変換 — API リクエストをワンクリックで Python コードに変換、HTTP クライアントを迅速に構築
Python の依存関係管理は、
easy_installからpipへ、requirements.txtからpoetry.lockへと長い進化を遂げてきた。uv の登場は単なる代替ではなく、Rust の高性能と Python の使いやすさを完璧に組み合わせ、依存関係管理を「我慢しなければならない痛み」から「ほぼ意識しない体験」へと変えた。2026 年、uv はあなたのデフォルトの選択になる準備ができている。
ブラウザローカルツールを無料で試す →