From 57d1495dd1350b1b703dd2eb1223efb2db9da7b6 Mon Sep 17 00:00:00 2001 From: wonder Date: Tue, 5 May 2026 20:12:00 +0800 Subject: [PATCH] vault backup: 2026-05-05 20:12:00 --- hzh/DEV/UV.md | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 hzh/DEV/UV.md diff --git a/hzh/DEV/UV.md b/hzh/DEV/UV.md new file mode 100644 index 0000000..f2f5249 --- /dev/null +++ b/hzh/DEV/UV.md @@ -0,0 +1,356 @@ +--- +tags: [uv, python, package-manager, virtualenv, dependency-management] +create time: 2026-05-05 15:30 +--- + +# UV — Fast Python Package Manager + +## 概述 + +UV 是 Astral(Ruff 的出品方)开发的极速 Python 包管理工具,用 Rust 编写。它同时承担 **包安装器**、**虚拟环境管理器** 和 **解析器** 三种角色,兼容 `pip`/`venv`/`virtualenv` 的工作流,但在性能上实现了数量级提升。 + +> [!tip] 为什么选择 UV? +> pip + venv + virtualenv + poetry 需要多个工具协作——每个工具职责不同、配置分散。UV 将安装包、管理虚拟环境、生成 lock 文件、管理多版本项目统一到一个 CLI 中。基准测试显示,`uv pip install` 比 pip 快 **10~100 倍**。 + +> [!question] 思考 +> 一个包管理工具为什么要重写为 Rust? +> —— Python 生态的依赖解析和下载是 I/O 密集型任务。Rust 提供了零成本抽象和极低的运行时开销,配合并发下载能力,这正是 pip(单线程 CPython 实现)难以企及的。 + +## 核心概念 + +### UV 与 pip/venv/poetry 的关系 + +```mermaid +graph TD + subgraph Traditional["传统工具链"] + P[pip — 包安装] + V[venv/virtualenv — 虚拟环境] + PO[poetry/pip-tools — 依赖锁定] + end + + subgraph UVChain["UV 工具链"] + A[uv pip — 包安装] + B[uv venv — 虚拟环境] + C[uv lock — 依赖锁定] + end + + Traditional --> D["三个独立工具配置分散"] + UVChain --> E["单一二进制零依赖"] + + classDef old fill:#fef3c7,color:#92400e + classDef new fill:#dcfce7,color:#166534 + classDef diff fill:#dbeafe,color:#1e3a8a + class P,V,PO old + class A,B,C new + class D,E diff +``` + +### 兼容模式 vs 原生模式 + +UV 支持两种使用方式: + +| 模式 | 核心命令 | 适用场景 | +|------|----------|----------| +| **`uv pip` 兼容模式** | `uv pip install` / `uv pip compile` | 从 pip 迁移,完全兼容 `requirements.txt` | +| **UV 原生模式** | `uv add` / `uv lock` / `uv run` | 新项目推荐,基于 `pyproject.toml` 现代化工作流 | + +> [!note] `uv pip` 与原生命令的区别 +> - `uv pip install` 安装到系统或虚拟环境中的 site-packages,行为与 pip 一致 +> - `uv add` 直接修改 `pyproject.toml` 中的依赖声明,并自动更新 `uv.lock`,适合有明确项目结构的项目 +> - 生产环境建议优先使用原生模式,因为 lock 文件确保所有开发者使用完全一致的依赖树 + +### pyproject.toml 中的 UV 配置 + +UV 使用标准 `pyproject.toml`,通过 `[tool.uv]` 表进行专属配置: + +```toml +[project] +name = "my-project" +version = "0.1.0" +requires-python = ">=3.11" +dependencies = [ + "fastapi>=0.110.0", + "httpx", +] + +[tool.uv] +dev-dependencies = [ + "pytest>=8.0", + "ruff>=0.4.0", +] + +# 指定 Python 源 +[[tool.uv.index]] +name = "pypi" +url = "https://pypi.org/simple/" + +# 私有源(如需) +#[[tool.uv.sources]] +#my-private-pkg = { index = "internal" } +``` + +## 安装 + +### 操作系统安装命令 + +```bash +# 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" + +# Homebrew / apt / scoop +brew install uv # macOS +apt install uv # Ubuntu(需先添加仓库) +scoop install uv # Windows +``` + +> [!tip] 验证安装 +> 安装完成后运行 `uv --version`,确认版本 ≥ 0.5.0。首次运行时 UV 会自动下载所需的 Python 版本并缓存,后续启动无需等待。 + +## 虚拟环境管理 + +### 创建与管理虚拟环境 + +```bash +# 创建虚拟环境(默认使用 .venv 目录) +uv venv + +# 指定 Python 版本(自动下载缺失版本) +uv venv --python 3.12 + +# 指定目标路径 +uv venv ./.venv-prod +``` + +创建成功后,激活方式与传统 venv 一致: + +```bash +# macOS / Linux +source .venv/bin/activate + +# Windows PowerShell +.venv\Scripts\Activate.ps1 +``` + +### uv run — 零激活执行 + +```bash +# 在虚拟环境中直接运行命令,无需手动激活 +uv run python main.py + +# 传递参数 +uv run pytest tests/ -v + +# 交互式 REPL +uv run python -i +``` + +> [!tip] 为什么推荐使用 `uv run`? +> 省去了 `source .venv/bin/activate` 和 `deactivate` 的手动步骤。CI/CD、脚本调用、编辑器集成都可以通过 `uv run` 一次性完成——它会自行查找 `.venv` 或使用 `pyproject.toml` 中声明的环境。 + +## 包管理与依赖 + +### 原生模式:`uv add` / `uv remove` + +```bash +# 添加生产依赖(写入 pyproject.toml + 更新 uv.lock) +uv add fastapi httpx + +# 添加开发依赖(写入 dev-dependencies) +uv add --dev pytest ruff mypy + +# 指定精确版本或范围 +uv add "requests>=2.31,<3" +uv add flask==3.0.0 + +# 从 Git 仓库安装 +uv add git+https://github.com/user/repo.git@branch + +# 移除依赖 +uv remove httpx +``` + +### `pip` 兼容模式:`uv pip` + +```bash +# 安装 requirements.txt(行为与 pip install -r 一致) +uv pip install -r requirements.txt + +# 生成锁文件(类似 pip-compile) +uv pip compile requirements.in -o requirements.locked.txt + +# 卸载包 +uv pip uninstall requests +``` + +### 版本解析策略 + +UV 使用基于 **回溯** 的高性能依赖解析器(由 pubgrub 算法驱动),与 Poetry 的行为语义相同: + +```mermaid +flowchart LR + A["用户请求: fastapi>=0.110 + httpx"] --> B{"解析依赖树"} + B --> C["发现冲突: A 要求 urllib3>=2, B 要求 urllib3<2"] + C --> D["尝试替换 B 为兼容版本"] + D -->|"解决"| E["输出唯一可行解 → uv.lock"] + D -->|"无解"| F["报错: 不可解析"] + + classDef ok fill:#dcfce7,color:#166534 + classDef fail fill:#f99,color:#7f1d1d + class E ok + class F fail +``` + +## Lock 文件 + +### `uv.lock` 的作用 + +`uv.lock` 是 UV 的依赖锁文件,记录的是经过解析后 **每一个子依赖的确切版本号**(不仅是顶层依赖)。这确保了: + +1. 不同机器、不同时间安装得到完全相同的依赖树 +2. CI/CD 环境可复现构建结果 +3. 避免 "在我机器上是好的" 问题 + +### 典型工作流 + +```bash +# 新增依赖(自动生成或更新 lock 文件) +uv add httpx + +# 手动更新 lock 文件(不改变 pyproject.toml,只更新锁定版本到最新兼容版) +uv lock + +# 安装 lock 文件中锁定的所有依赖 +uv sync + +# 同步但排除 dev 依赖(生产环境) +uv sync --no-dev +``` + +> [!info] uv sync vs pip install -r +> - `uv sync` 会严格对照 `uv.lock` 安装——移除多余的、更新过期的、安装缺失的 +> - `pip install -r` 只看 `requirements.txt`,不会主动清理已安装但未声明的包 +> - 推荐始终使用 `uv sync` 代替 `pip install -e .` + +## 多项目工作区(Workspace) + +UV 支持 Monorepo 风格的多项目组织: + +```toml +# pyproject.toml at workspace root +[project] +name = "workspace-root" +version = "0.1.0" +requires-python = ">=3.11" + +[tool.uv.workspace] +members = ["packages/*"] +optional-groups = ["docs"] +``` + +```toml +# packages/web/pyproject.toml +[project] +name = "web-service" +dependencies = ["shared-lib"] # 引用 workspace 内的其他项目 +``` + +```toml +# packages/lib/pyproject.toml +[project] +name = "shared-lib" +``` + +```bash +# 在工作区根目录操作 +uv lock # 解析整个工作区的依赖 +uv sync # 安装所有成员包的依赖 +uv add -p web-service fastapi # 只为特定成员添加依赖 +``` + +## 实战示例 + +### 创建一个 FastAPI 项目 + +```bash +# ① 创建项目并初始化 venv +uv init my-api +cd my-api +uv venv --python 3.12 + +# ② 添加依赖 +uv add fastapi uvicorn httpx +uv add --dev ruff pytest + +# ③ 运行项目 +uv run uvicorn main:app --reload + +# ④ 运行测试 +uv run pytest tests/ -v +``` + +### CI/CD 流水线集成 + +```yaml +# .github/workflows/ci.yml(简化版) +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install UV + run: curl -LsSf https://astral.sh/uv/install.sh | sh + + - name: Sync dependencies + run: uv sync --all-extras --frozen + + - name: Run tests + run: uv run pytest tests/ -v + + - name: Lint + run: uv run ruff check . +``` + +> [!warning] `--frozen` 标志的含义 +> 加上 `--frozen` 时,如果 `uv.lock` 不存在或与 `pyproject.toml` 不一致,命令会直接失败而非自动更新。这在 CI 中很重要——确保 lock 文件的变更必须经过代码审查提交。 + +## 常用命令速查 + +| 命令 | 说明 | 等价命令 | +|------|------|----------| +| `uv add ` | 添加依赖到 pyproject.toml | `uv pip install` | +| `uv remove ` | 从依赖中移除 | `uv pip uninstall` | +| `uv sync` | 按 lock 文件同步环境 | `pip install -e .` | +| `uv lock` | 生成/更新 lock 文件 | `poetry lock` | +| `uv run ` | 在环境内执行命令 | `source .venv/bin/activate && cmd` | +| `uv venv` | 创建虚拟环境 | `python -m venv .venv` | +| `uv python list` | 列出可安装的 Python 版本 | `pyenv versions` | +| `uv python install 3.12` | 下载并缓存指定 Python | `pyenv install 3.12` | +| `uv pin 3.11` | 锁定项目 Python 版本 | 设置 `.python-version` | +| `uv export` | 导出为 requirements.txt | `pip freeze > req.txt` | + +## 与其他工具的对比 + +| 维度 | pip + venv | Poetry | uv | +|------|-----------|--------|-----| +| 语言 | Python | Python | Rust | +| 安装速度 | 慢(单线程) | 中等 | ⚡ 极快(并发) | +| 虚拟环境 | `venv` 独立命令 | `poetry env` | `uv venv` 内置 | +| Lock 文件 | 需 pip-compile | `poetry.lock` | `uv.lock` | +| pyproject.toml | 第三方支持 | ✅ 原生 | ✅ 原生 | +| 多项目/Workspace | ❌ | ✅ | ✅ | +| Python 版本管理 | ❌ 需 pyenv | ❌ 需 pyenv | ✅ `uv python install` | +| 依赖大小 | 无额外依赖 | 较重 | 单个二进制 ~15MB | +| 成熟度 | 事实标准 | 高 | 快速迭代中 | + +> [!info] 迁移建议 +> - **pip 用户** → 直接使用 `uv pip` 命令获得加速,零迁移成本 +> - **Poetry 用户** → `uv` 的 `add/sync/lock` 工作流与 Poetry 高度相似,学习曲线平缓 +> - **新项目** → 直接用 `uv` 原生命令 + `pyproject.toml` + `uv.lock` + +## 关联笔记 + +- [[hzh/DEV/Husky]] — Git Hooks 管理(可与 uv run 结合在 pre-commit 中运行 lint)