uv 完全指南

uv 是由 Astral(Ruff 的开发团队)用 Rust 编写的 Python 包管理器和项目管理工具。它将 pip、pip-tools、pipx、pyenv、virtualenv 的功能集成到一个工具中,速度比 pip 快 10-100 倍。 相关文档:Python包管理工具(/python-bao-guan-li-gong-ju/) | FastAPI完全指南(/fastapi-wan-quan-zhi-nan/) | pytest完全指南(/pytest-wan-quan-zhi-nan/) uv 是一个"全能型"Python 工具链,可替代多

分享

官方文档:https://docs.astral.sh/uv/
适用版本:uv 0.4+(2026-05-07 核实)

uv 是由 Astral(Ruff 的开发团队)用 Rust 编写的 Python 包管理器和项目管理工具。它将 pip、pip-tools、pipx、pyenv、virtualenv 的功能集成到一个工具中,速度比 pip 快 10-100 倍。

相关文档:Python包管理工具 | FastAPI完全指南 | pytest完全指南


基础概念

uv 的定位

uv 是一个"全能型"Python 工具链,可替代多个现有工具:

被替代的工具 uv 对应功能
pip uv pip install / uv add
pip-tools uv pip compile / uv lock
pipx uv tool install / uvx
pyenv uv python install
virtualenv / venv uv venv
poetry / pdm uv init + 项目管理命令

核心文件

文件 作用 是否提交版本控制
pyproject.toml 项目元数据和依赖声明(人工维护)
uv.lock 精确锁定所有依赖版本(uv 自动维护)
.python-version 项目 Python 版本锁定
.venv/ 虚拟环境目录
uv.toml uv 全局/工作区级配置

uv.lock 说明

uv.lock 是跨平台锁定文件,记录所有 Python 标记(操作系统、CPU 架构、Python 版本)下会安装的精确版本。格式为人类可读的 TOML,但不应手动编辑。

requirements.txt 的区别:uv.lock 包含所有平台的信息,而 requirements.txt 只记录当前平台的安装结果。


安装

安装方式

# 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"

# 安装指定版本
curl -LsSf https://astral.sh/uv/0.6.0/install.sh | sh

# 通过 Homebrew(macOS/Linux)
brew install uv

# 通过 pip(不推荐,但可用)
pip install uv

# 通过 pipx
pipx install uv

自更新与卸载

# 更新到最新版本
uv self update

# 查看版本
uv --version

# 卸载(先清理缓存)
uv cache clean
# 然后删除二进制文件(通常在 ~/.cargo/bin/uv 或 ~/.local/bin/uv)

Shell 补全

# Bash
echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc

# Zsh
echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc

# Fish
echo 'uv generate-shell-completion fish | source' >> ~/.config/fish/config.fish

# PowerShell
Add-Content $PROFILE '(& uv generate-shell-completion powershell) | Out-String | Invoke-Expression'

Python 版本管理

uv 内置 Python 版本管理,无需 pyenv 等额外工具。

uv python install

安装指定 Python 版本(来自 python-build-standalone 项目)。

uv python install [OPTIONS] [TARGETS]...
参数/选项 类型 默认值 说明
TARGETS str - 版本号,如 3.123.11.9pypy3.10
--reinstall / -r flag 关闭 重新安装已有版本
--upgrade / -U flag 关闭 将已安装版本升级到最新补丁版本
--force / -f flag 关闭 强制替换已有的 Python 可执行文件
--default flag 关闭 将安装的版本设为默认 Python
# 安装最新 Python 3.12
uv python install 3.12

# 安装多个版本
uv python install 3.11 3.12 3.13

# 安装 PyPy
uv python install pypy3.10

# 安装特定补丁版本
uv python install 3.12.3

uv python list

列出可用和已安装的 Python 版本。

uv python list [OPTIONS]
参数/选项 类型 默认值 说明
--only-installed flag 关闭 只显示已安装的版本
--all-versions flag 关闭 显示所有可用版本(含补丁)
--all-platforms flag 关闭 显示其他平台的版本
uv python list
uv python list --only-installed
uv python list --all-versions

uv python pin

固定项目使用的 Python 版本,写入 .python-version 文件。

uv python pin [OPTIONS] [REQUEST]
参数/选项 类型 默认值 说明
REQUEST str - 版本号,如 3.12
--resolved flag 关闭 写入完整的解析版本号(如 3.12.3
--global flag 关闭 写入全局配置而非项目目录
--rm flag 关闭 删除 .python-version 文件中的版本锁定
--no-project flag 关闭 不验证版本与项目的兼容性
uv python pin 3.12
uv python pin 3.12.3 --resolved

uv python find

查找匹配条件的 Python 解释器路径。

uv python find [REQUEST]
uv python find 3.12
# 输出:/home/user/.local/share/uv/python/cpython-3.12.3-.../bin/python3

uv python uninstall

卸载已安装的 Python 版本。

uv python uninstall [TARGETS]...
uv python uninstall 3.11
uv python uninstall --all  # 卸载所有 uv 管理的 Python

uv python upgrade

升级已安装的 Python 到最新补丁版本。

uv python upgrade 3.12  # 升级 3.12.x 到最新补丁
uv python upgrade --all  # 升级所有已安装版本

Python 版本解析优先级

uv 按以下顺序查找 Python:

  1. --python 命令行参数
  2. UV_PYTHON 环境变量
  3. 当前项目的 .python-version 文件
  4. pyproject.toml 中的 requires-python
  5. 父目录的 .python-version 文件
  6. 系统 PATH 中的 Python

项目管理

uv init

初始化新项目,创建 pyproject.toml 等基础文件。

uv init [OPTIONS] [PATH]
参数/选项 类型 默认值 说明
PATH str 当前目录 项目目录路径
--name str 目录名 项目名称
--python str - 指定 Python 版本
--app flag 默认 初始化为应用程序(不含 src 布局)
--lib flag 关闭 初始化为库(含 src/ 布局,有 __init__.py
--package flag 关闭 初始化为可打包应用(含 src 布局,有构建系统)
--script flag 关闭 初始化为单文件脚本(含 PEP 723 内联元数据)
--bare flag 关闭 最小化初始化(不生成 README、.python-version、示例文件)
--build-backend str uv 构建后端,可选 hatchflitpdmsetuptoolsmaturinscikit
--vcs str git 版本控制系统,none 禁用
--no-readme flag 关闭 不生成 README.md
--no-pin-python flag 关闭 不生成 .python-version
# 创建应用项目(默认)
uv init my-app
# 生成:pyproject.toml、README.md、.python-version、hello.py

# 创建库项目
uv init --lib my-library
# 生成:pyproject.toml、README.md、.python-version、src/my_library/__init__.py

# 创建可打包应用
uv init --package my-package

# 指定构建后端
uv init --lib --build-backend hatch my-library

# 最小化初始化(适合在已有目录中使用)
uv init --bare

# 在当前目录初始化(不创建子目录)
uv init

项目类型对比

项目类型 命令 目录结构 用途
应用 (app) uv init --app 根目录直接放 .py 文件 脚本、服务、CLI 应用
库 (lib) uv init --lib src/包名/ 布局 发布到 PyPI 的库
可打包应用 uv init --package src/ 布局 + 构建系统 需要打包分发的应用
脚本 uv init --script 单 .py 文件 单文件独立脚本

应用项目(--app,默认)没有构建系统,不能用 uv build 打包,适合部署到服务器或容器。

库项目(--lib)有构建系统,可以用 uv build 生成 wheel,适合发布到 PyPI。


依赖管理

uv add

添加依赖到 pyproject.toml 并更新 uv.lock,同时安装到虚拟环境。

uv add [OPTIONS] <PACKAGES>...
参数/选项 类型 默认值 说明
PACKAGES str 必填 包名,支持 PEP 440 版本约束
--dev / -d flag 关闭 添加到 dev 依赖组
--group str - 添加到指定依赖组,如 --group test
--optional str - 添加为可选依赖(extras),如 --optional network
--editable / -e flag 关闭 以可编辑模式安装本地包
--raw-sources flag 关闭 不将来源规范化到 tool.uv.sources
--no-sync flag 关闭 只修改 pyproject.toml,不安装到环境
--frozen flag 关闭 不更新 uv.lock(也不重新锁定)
--locked flag 关闭 要求 uv.lock 不发生变化,否则报错
--bounds str - 版本约束方式:lowermajorminorexact
--raw flag 关闭 按原样写入依赖字符串,不规范化来源到 tool.uv.sources
--branch str - Git 分支(与 git+https://... 包名一起使用)
--tag str - Git 标签(与 git+https://... 包名一起使用)
--rev str - Git 提交哈希(与 git+https://... 包名一起使用)
--lfs flag 关闭 使用 Git LFS 拉取 Git 依赖
--script str - 将依赖添加到指定脚本文件(PEP 723)
# 添加生产依赖
uv add requests
uv add "fastapi>=0.100.0"
uv add "sqlalchemy[asyncio]>=2.0"

# 同时添加多个包
uv add requests httpx aiohttp

# 添加开发依赖
uv add --dev pytest ruff mypy

# 添加到指定依赖组
uv add --group lint ruff pyflakes
uv add --group test pytest pytest-asyncio coverage

# 添加可选依赖(extras)
uv add --optional network httpx aiohttp

# 本地可编辑包
uv add --editable ./packages/my-utils

# Git 依赖(URL 直接写在包名位置,--branch/--tag/--rev 控制引用)
uv add "git+https://github.com/user/repo"
uv add "git+https://github.com/user/repo" --branch main
uv add "git+https://github.com/user/repo" --tag v1.0.0
uv add "git+https://github.com/user/repo" --rev abc1234

# 平台特定依赖(通过环境标记)
uv add "pywinpty; sys_platform == 'win32'"
uv add "uvloop; sys_platform != 'win32'"

# 版本约束方式
uv add fastapi --bounds major    # >=0.115.5, <1
uv add fastapi --bounds minor    # >=0.115.5, <0.116
uv add fastapi --bounds exact    # ==0.115.5
uv add fastapi --bounds lower    # >=0.115.5(只设下界)

# 为脚本添加依赖(PEP 723)
uv add --script my_script.py requests rich

uv remove

移除依赖,更新 pyproject.tomluv.lock

uv remove [OPTIONS] <PACKAGES>...
参数/选项 类型 默认值 说明
PACKAGES str 必填 包名
--dev flag 关闭 从 dev 组移除
--group str - 从指定组移除
--optional str - 从指定可选依赖移除
--no-sync flag 关闭 只修改 pyproject.toml,不更新环境
--script str - 从脚本文件移除依赖
uv remove requests
uv remove --dev pytest
uv remove --group lint ruff
uv remove --optional network httpx

依赖类型说明

uv 支持四种依赖类型,对应不同的使用场景:

依赖类型 pyproject.toml 字段 添加命令 是否发布 说明
生产依赖 project.dependencies uv add 运行时必须
可选依赖 project.optional-dependencies uv add --optional 按需安装的 extras
依赖组 dependency-groups uv add --group 仅本地使用,不发布
dev 依赖 dependency-groups.dev uv add --dev dev 组的简写

依赖源(tool.uv.sources)

pyproject.toml 中配置非 PyPI 的依赖来源:

[tool.uv.sources]
# 本地路径(可编辑)
my-utils = { path = "./packages/my-utils", editable = true }

# 本地路径(不可编辑)
my-lib = { path = "../my-lib" }

# Git 仓库
my-git-pkg = { git = "https://github.com/user/repo", branch = "main" }
my-tagged-pkg = { git = "https://github.com/user/repo", tag = "v1.0.0" }
my-rev-pkg = { git = "https://github.com/user/repo", rev = "abc1234" }

# 工作区成员
shared-lib = { workspace = true }

# 指定索引
torch = { index = "pytorch" }

tool.uv.index
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"

锁定与同步

uv lock

创建或更新 uv.lock 锁定文件,解析所有依赖版本。

uv lock [OPTIONS]
参数/选项 类型 默认值 说明
--upgrade flag 关闭 升级所有依赖到最新兼容版本
--upgrade-package str - 只升级指定包
--check flag 关闭 检查锁定文件是否最新,否则报错(不写入)
--check-exists flag 关闭 只检查 uv.lock 是否存在,不验证内容
--dry-run flag 关闭 显示将要变更的内容,不实际写入
--python str - 指定解析时使用的 Python 版本
--index str - 使用指定包索引
--no-sources flag 关闭 忽略 tool.uv.sources 配置(生成可发布的锁定文件)
--script str - 锁定指定 PEP 723 脚本而非项目
# 生成/更新锁定文件
uv lock

# 升级所有依赖
uv lock --upgrade

# 升级单个包
uv lock --upgrade-package requests

# 升级到指定版本
uv lock --upgrade-package "requests==2.32.0"

# 验证锁定文件是否最新(CI 中常用,不写入)
uv lock --check

# 只查看变化,不写入
uv lock --dry-run

uv sync

将虚拟环境与 uv.lock 同步,使环境与锁定文件完全一致。

uv sync [OPTIONS]
参数/选项 类型 默认值 说明
--frozen flag 关闭 不更新 uv.lock,直接用现有锁定文件安装
--locked flag 关闭 要求 uv.lock 是最新的,否则报错(不自动更新)
--no-sync flag 关闭 不同步环境(仅解析)
--exact flag 关闭 精确同步,移除锁定文件中没有的包
--inexact flag 默认 不移除多余的包
--dev / --no-dev flag dev 是否安装 dev 依赖
--only-dev flag 关闭 只安装 dev 依赖
--group str - 安装指定依赖组
--all-groups flag 关闭 安装所有依赖组
--no-group str - 排除指定依赖组
--extra str - 安装指定可选依赖
--all-extras flag 关闭 安装所有可选依赖
--no-install-project flag 关闭 不安装项目本身(只安装依赖)
--no-install-workspace flag 关闭 不安装工作区成员
--no-install-package str - 不安装指定包
--python str - 指定 Python 版本
# 标准同步(安装所有依赖含 dev)
uv sync

# 仅同步生产依赖(适合部署)
uv sync --no-dev

# 安装所有可选依赖
uv sync --all-extras

# 安装指定可选依赖
uv sync --extra docs --extra test

# CI 环境(不更新锁定文件)
uv sync --frozen

# 生产部署(要求锁定文件最新且不自动更新)
uv sync --locked --no-dev

# 精确同步(移除多余包,适合生产环境)
uv sync --exact --no-dev

# 安装依赖但不安装项目本身(Docker 分层优化)
uv sync --no-install-project

自动锁定与同步

uv runuv syncuv adduv remove 都会自动执行锁定和同步,无需手动调用 uv lock

可以通过以下方式控制自动行为:

# 禁止自动更新锁定文件(如锁定文件过期则报错)
uv run --locked python main.py

# 禁止检查锁定文件(直接使用,不验证是否最新)
uv run --frozen python main.py

运行命令

uv run

在项目虚拟环境中执行命令,自动完成环境同步。

uv run [OPTIONS] [COMMAND]
参数/选项 类型 默认值 说明
COMMAND str 必填 要执行的命令或脚本路径
--with str - 临时安装额外包(不写入项目依赖)
--with-editable str - 临时以可编辑模式安装本地包
--without str - 临时排除指定包
--python str - 指定 Python 版本
--frozen flag 关闭 不更新 uv.lock
--locked flag 关闭 要求 uv.lock 是最新的
--no-sync flag 关闭 不同步环境
--isolated flag 关闭 在隔离环境中运行(不使用项目依赖)
--env-file str - 加载 .env 文件中的环境变量
--no-project flag 关闭 不在项目上下文中运行
--package str - 在指定工作区成员的上下文中运行
--group str - 包含指定依赖组
--all-groups flag 关闭 包含所有依赖组
--extra str - 包含指定可选依赖
--script flag 关闭 将命令当作 PEP 723 脚本运行
# 运行 Python 脚本
uv run python main.py
uv run main.py  # 也可以省略 python

# 运行项目中的工具
uv run pytest
uv run pytest tests/test_api.py -v
uv run ruff check .
uv run mypy src/

# 临时安装包运行(不污染项目依赖)
uv run --with rich python -c "import rich; rich.print('[bold]Hello[/bold]')"
uv run --with "httpx>=0.24" python fetch.py

# 使用 .env 文件
uv run --env-file .env python main.py

# 在工作区特定成员中运行
uv run --package api pytest tests/

# 带 frozen 标志(CI 环境,不更新锁定文件)
uv run --frozen pytest

脚本管理(PEP 723)

PEP 723 定义了在 Python 脚本中内联声明依赖的标准格式,uv 完整支持。

内联依赖声明

在脚本文件顶部添加元数据块:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "requests",
#     "rich>=13.0",
# ]
# ///

import requests
from rich import print

response = requests.get("https://api.github.com")
print(response.json())
# 运行含内联依赖的脚本(uv 自动创建隔离环境并安装依赖)
uv run my_script.py

# 也可以显式指定
uv run --script my_script.py

为脚本添加/移除依赖

# 添加依赖到脚本(自动修改脚本文件的元数据块)
uv add --script my_script.py requests rich

# 移除脚本依赖
uv remove --script my_script.py requests

# 查看脚本依赖
uv run my_script.py --help

可执行脚本(Shebang)

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = ["requests"]
# ///

import requests
print(requests.get("https://httpbin.org/get").status_code)
chmod +x my_script.py
./my_script.py  # 直接运行,uv 自动处理依赖

锁定脚本依赖

# 为脚本生成锁定文件(在脚本同目录创建 my_script.py.lock)
uv lock --script my_script.py

# 使用锁定文件运行(确保可重现)
uv run --locked my_script.py

工具管理

工具(tool)是安装到隔离环境并暴露可执行文件到 PATH 的命令行程序,不污染任何项目的依赖。

uvx(uv tool run)

临时运行工具,不永久安装。

uvx [OPTIONS] [COMMAND] [ARGS]...
# 等同于 uv tool run
参数/选项 类型 默认值 说明
COMMAND str 必填 工具名称或入口点
--from str - 指定包名(当工具名与包名不同时)
--with str - 额外安装的包(如插件)
--python str - 指定工具的 Python 版本
--isolated flag 关闭 不使用缓存,创建全新隔离环境
# 临时运行工具
uvx ruff check .
uvx black --check .
uvx httpie GET https://httpbin.org/get

# 指定版本运行
uvx [email protected] check .
uvx --from "ruff==0.3.0" ruff check .
uvx --from "ruff>0.2.0,<0.4.0" ruff check .

# 带 extras 运行
uvx --from "mypy[faster-cache,reports]" mypy src/

# 带额外包运行(如 mkdocs 插件)
uvx --with mkdocs-material mkdocs serve

# 从 Git 运行
uvx --from "git+https://github.com/user/tool" tool-name

uv tool install

永久安装工具,添加到 PATH。

uv tool install [OPTIONS] <PACKAGE>
参数/选项 类型 默认值 说明
PACKAGE str 必填 工具包名
--python str - 指定工具使用的 Python 版本
--with str - 同时安装额外包
--force flag 关闭 强制重新安装(覆盖已有版本)
--editable / -e flag 关闭 可编辑安装
# 安装常用工具
uv tool install ruff
uv tool install mypy
uv tool install black
uv tool install cookiecutter
uv tool install httpie

# 安装特定版本
uv tool install "ruff==0.3.0"

# 安装带插件的工具
uv tool install mkdocs --with mkdocs-material --with mkdocs-minify-plugin

# 从 Git 安装
uv tool install "git+https://github.com/user/tool"

uv tool list

列出已安装的工具。

uv tool list [OPTIONS]
参数/选项 类型 默认值 说明
--show-paths flag 关闭 显示工具安装路径
uv tool list
uv tool list --show-paths

uv tool upgrade

升级已安装的工具。

uv tool upgrade [OPTIONS] [NAMES]...
参数/选项 类型 默认值 说明
NAMES str - 工具名,省略则升级全部
--all flag 关闭 升级所有工具
--python str - 指定 Python 版本
uv tool upgrade ruff
uv tool upgrade --all

uv tool uninstall

卸载工具。

uv tool uninstall [NAMES]...
uv tool uninstall ruff
uv tool uninstall --all

uv tool dir

查看工具安装目录。

uv tool dir  # 输出工具的 bin 目录路径

虚拟环境管理

uv venv

创建虚拟环境(pip 工作流使用,项目模式下 uv 自动管理 .venv)。

uv venv [OPTIONS] [PATH]
参数/选项 类型 默认值 说明
PATH str .venv 虚拟环境目录路径
--python / -p str 系统 Python 指定 Python 版本
--seed flag 关闭 预安装 pip、setuptools、wheel
--system-site-packages flag 关闭 允许访问系统级 Python 包
--no-project flag 关闭 不关联到项目(忽略 pyproject.toml)
--allow-existing flag 关闭 允许覆盖已有虚拟环境
--relocatable flag 关闭 创建可迁移的虚拟环境
# 创建默认虚拟环境
uv venv

# 指定 Python 版本
uv venv --python 3.12
uv venv --python pypy3.10

# 指定路径
uv venv /path/to/myenv
uv venv .venv-py312

# 带 pip 的虚拟环境(传统工作流)
uv venv --seed

# 激活虚拟环境
source .venv/bin/activate      # Linux/macOS
.venv\Scripts\activate          # Windows CMD
.venv\Scripts\Activate.ps1      # Windows PowerShell

deactivate  # 退出

pip 兼容接口

uv 提供与 pip、pip-tools、virtualenv 兼容的命令接口,便于迁移。

uv pip install

uv pip install [OPTIONS] <PACKAGES>...
# 基本安装
uv pip install requests

# 从 requirements.txt 安装
uv pip install -r requirements.txt

# 可编辑安装
uv pip install -e .

# 指定索引
uv pip install --index-url https://pypi.org/simple/ requests

# 不使用缓存
uv pip install --no-cache requests

uv pip compile

将依赖声明编译为精确锁定的 requirements.txt

uv pip compile [OPTIONS] <SRC_FILE>...
参数/选项 类型 默认值 说明
SRC_FILE str 必填 输入文件(requirements.in 或 pyproject.toml)
--output-file / -o str stdout 输出文件路径
--upgrade / -U flag 关闭 升级所有包到最新版本
--upgrade-package / -P str - 升级指定包
--generate-hashes flag 关闭 生成包哈希值(提高安全性)
--python str - 指定目标 Python 版本
--extra str - 包含指定可选依赖
--all-extras flag 关闭 包含所有可选依赖
--no-annotate flag 关闭 不添加注释(包来源说明)
# 编译 requirements.in -> requirements.txt
uv pip compile requirements.in -o requirements.txt

# 从 pyproject.toml 编译(生产依赖)
uv pip compile pyproject.toml -o requirements.txt

# 含开发依赖
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt

# 升级并重新编译
uv pip compile requirements.in --upgrade -o requirements.txt

# 带哈希值(安全部署)
uv pip compile requirements.in --generate-hashes -o requirements.txt

uv pip sync

将环境精确同步到 requirements.txt 中指定的包(会移除多余的包)。

uv pip sync [OPTIONS] <SRC_FILE>...
uv pip sync requirements.txt
uv pip sync requirements.txt requirements-dev.txt
uv pip sync --frozen requirements.txt  # 不验证哈希

uv pip list / show / check / tree

# 列出已安装的包
uv pip list
uv pip list --format json

# 显示包详情
uv pip show requests

# 检查依赖兼容性
uv pip check

# 显示依赖树
uv pip tree
uv pip tree --package requests  # 只显示指定包的依赖树

uv pip uninstall

uv pip uninstall requests
uv pip uninstall -r requirements.txt

构建与发布

uv build

构建源代码分发包(sdist)和二进制分发包(wheel)。

uv build [OPTIONS] [SRC]
参数/选项 类型 默认值 说明
SRC str 当前目录 要构建的项目路径
--sdist flag 关闭 只构建源码分发包
--wheel flag 关闭 只构建 wheel
--out-dir / -o str dist/ 输出目录
--no-sources flag 关闭 忽略 tool.uv.sources(确保与其他构建工具兼容)
--build-constraint str - 约束构建依赖的版本
# 构建 wheel 和 sdist
uv build

# 只构建 wheel
uv build --wheel

# 只构建 sdist
uv build --sdist

# 指定输出目录
uv build -o ./dist

# 为发布构建(不含本地 sources 配置)
uv build --no-sources

uv version

查看或修改项目版本号。

uv version [OPTIONS] [VALUE]
参数/选项 类型 默认值 说明
VALUE str - 新版本号,省略则显示当前版本
--bump str - 语义化版本自动递增:majorminorpatchstablealphabetarcpostdev
--dry-run flag 关闭 只显示结果,不写入
--output-format str text 输出格式:textjson
--short flag 关闭 只输出版本号
# 查看当前版本
uv version
uv version --short  # 只输出版本号

# 设置版本
uv version 1.2.3

# 自动递增
uv version --bump patch   # 1.0.0 -> 1.0.1
uv version --bump minor   # 1.0.0 -> 1.1.0
uv version --bump major   # 1.0.0 -> 2.0.0
uv version --bump alpha   # 1.0.0 -> 1.0.0a1
uv version --bump rc      # 1.0.0a1 -> 1.0.0rc1

# 预览变化
uv version --bump minor --dry-run

uv publish

将构建产物发布到 PyPI 或其他包索引。

uv publish [OPTIONS] [FILES]...
参数/选项 类型 默认值 说明
FILES str dist/* 要发布的文件路径
--publish-url str PyPI 发布目标 URL
--token / -t str - PyPI API token
--username / -u str - 用户名(不推荐,PyPI 已不支持用户名密码)
--password / -p str - 密码
--check-url str - 发布前检查的索引 URL(避免重复上传)
--trusted-publishing str - 可信发布模式:alwaysautomatic(GitHub Actions 推荐)
# 发布到 PyPI(需先配置 token)
uv publish --token pypi-xxxx

# 通过环境变量(推荐)
UV_PUBLISH_TOKEN=pypi-xxxx uv publish

# 发布到私有仓库
uv publish --publish-url https://my.private.repo/upload/

# 发布指定文件
uv publish dist/my_package-1.0.0-py3-none-any.whl

完整发布流程

# 1. 更新版本
uv version --bump minor

# 2. 构建(不含本地 sources)
uv build --no-sources

# 3. 验证构建产物(可选,使用 twine check)
uvx twine check dist/*

# 4. 发布
UV_PUBLISH_TOKEN=pypi-xxxx uv publish

# 5. 验证安装
uv run --with my-package --no-project python -c "import my_package; print(my_package.__version__)"

工作区(Workspaces)

工作区将多个相关 Python 包组织在同一仓库中,共享一个 uv.lock 文件,适合 monorepo 架构。

核心概念

  • 工作区根:包含 [tool.uv.workspace] 的项目,也是一个工作区成员
  • 工作区成员:工作区中的每个包,各自有独立的 pyproject.toml
  • 共享锁定文件:所有成员共享根目录的 uv.lock,确保依赖一致性
  • 共享虚拟环境:所有成员安装到同一个 .venv

工作区结构

my-workspace/
├── pyproject.toml          # 工作区根(含 [tool.uv.workspace])
├── uv.lock                 # 所有成员共享的锁定文件
├── .venv/                  # 所有成员共享的虚拟环境
├── packages/
│   ├── core/
│   │   ├── pyproject.toml  # 工作区成员
│   │   └── src/core/
│   ├── api/
│   │   ├── pyproject.toml  # 工作区成员
│   │   └── src/api/
│   └── cli/
│       ├── pyproject.toml  # 工作区成员
│       └── src/cli/
└── apps/
    └── web/
        ├── pyproject.toml  # 工作区成员
        └── src/web/

配置工作区

工作区根的 pyproject.toml

[project]
name = "my-workspace"
version = "0.1.0"
requires-python = ">=3.12"

[tool.uv.workspace]
members = ["packages/*", "apps/*"]
# exclude 用于排除匹配 members 的特定目录
exclude = ["packages/experimental"]

成员的 pyproject.toml

[project]
name = "core"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

工作区成员间依赖

成员之间通过 tool.uv.sources 相互引用:

# packages/api/pyproject.toml
[project]
name = "api"
dependencies = ["core"]

[tool.uv.sources]
core = { workspace = true }

等同于可编辑安装,修改 core 的代码立即在 api 中生效,无需重新安装。

工作区命令

# 在工作区根执行:对所有成员操作
uv lock            # 为整个工作区解析依赖
uv sync            # 同步整个工作区的虚拟环境

# 针对特定成员
uv run --package api pytest tests/
uv sync --package core
uv add --package api fastapi

工作区限制

限制 说明
单一 requires-python 工作区取所有成员 requires-python 的交集
不支持冲突依赖 成员间如有不兼容的依赖版本,无法使用工作区
不支持多虚拟环境 工作区只有一个 .venv,如需隔离请用路径依赖
根必须是成员 工作区根本身也是一个工作区成员(但可以是虚包)

虚根(Virtual Workspace Root)

如果工作区根只是容器,不需要本身作为包,可以将其配置为虚包(不含 build-system):

# 工作区根 pyproject.toml(虚根)
[project]
name = "my-workspace"
version = "0.1.0"
# 不含 [build-system],是一个"非包"项目

[tool.uv.workspace]
members = ["packages/*"]

大型与复杂项目管理

单体仓库(Monorepo)最佳实践

推荐结构:

my-monorepo/
├── pyproject.toml          # 工作区根(虚根)
├── uv.lock
├── .python-version         # 统一 Python 版本
├── uv.toml                 # 全局 uv 配置
├── packages/
│   ├── shared/             # 共享工具库
│   ├── models/             # 数据模型
│   └── utils/              # 通用工具
├── services/
│   ├── api-service/        # FastAPI 服务
│   ├── worker-service/     # Celery Worker
│   └── admin-service/      # 管理后台
└── tools/
    └── scripts/            # 运维脚本

工作区根配置:

[project]
name = "my-monorepo"
version = "0.1.0"
requires-python = ">=3.12"

[tool.uv.workspace]
members = ["packages/*", "services/*", "tools/*"]

[tool.uv]
# 全局约束(覆盖所有成员的相同包版本)
constraint-dependencies = [
    "pydantic>=2.0",
]

依赖冲突解决

当成员之间有不兼容依赖时,通过 override-dependencies 强制统一:

# 工作区根 pyproject.toml
[tool.uv]
# 强制所有成员使用此版本(跳过成员自己的约束)
override-dependencies = [
    "numpy==1.26.4",
]

通过 constraint-dependencies 添加约束而不覆盖:

[tool.uv]
# 在成员约束基础上额外添加约束
constraint-dependencies = [
    "certifi>=2024.0",
]

依赖组嵌套(适合大型项目)

在复杂项目中,通过依赖组组合管理不同场景的依赖:

[dependency-groups]
# 基础开发工具
dev = ["ruff>=0.4", "mypy>=1.9"]

# 测试依赖
test = ["pytest>=8.0", "pytest-asyncio>=0.23", "coverage>=7.0"]

# 文档
docs = ["mkdocs>=1.5", "mkdocs-material>=9.0"]

# 完整开发环境(包含所有组)
full = [
    { include-group = "dev" },
    { include-group = "test" },
    { include-group = "docs" },
]

安装特定场景:

uv sync --group test                 # 只安装测试依赖
uv sync --group full                 # 安装完整开发环境
uv sync --no-dev --no-group docs     # 只安装生产依赖,排除 docs 组

条件依赖(平台/版本特定)

[project]
dependencies = [
    # Python 版本条件
    "tomllib; python_version < '3.11'",
    "importlib-metadata>=6.0; python_version < '3.12'",
    # 平台条件
    "pywin32>=306; sys_platform == 'win32'",
    "uvloop>=0.19; sys_platform != 'win32'",
    # CPU 架构条件
    "nvidia-cuda-runtime-cu12; platform_machine == 'x86_64' and sys_platform == 'linux'",
]

多 Python 版本测试

# 为不同 Python 版本创建独立的虚拟环境(临时)
uv run --python 3.10 pytest
uv run --python 3.11 pytest
uv run --python 3.12 pytest

# 结合 tox 或 nox 进行矩阵测试
# noxfile.py 中配置
# nox.options.sessions = ["test-3.10", "test-3.11", "test-3.12"]

路径依赖 vs 工作区

特性 路径依赖 工作区成员
锁定文件 各项目独立的 uv.lock 共享一个 uv.lock
虚拟环境 各项目独立的 .venv 共享一个 .venv
冲突依赖 可以有不同版本 必须统一版本
适合场景 需要隔离的子项目 紧密耦合的包集合
# 路径依赖(各自独立的锁定文件和环境)
[project]
dependencies = ["my-utils"]

[tool.uv.sources]
my-utils = { path = "../my-utils", editable = true }

包索引配置

配置私有/镜像索引

pyproject.tomluv.toml 中配置:

tool.uv.index
name = "aliyun"
url = "https://mirrors.aliyun.com/pypi/simple/"

tool.uv.index
name = "tencent"
url = "https://mirrors.cloud.tencent.com/pypi/simple/"

# 私有仓库
tool.uv.index
name = "private"
url = "https://private.company.com/simple/"
# 设为默认索引(替换 PyPI)
default = true

索引优先级:命令行 --index > 配置文件中靠前的索引 > PyPI(默认)。

索引搜索策略

[tool.uv]
# first-index(默认):找到包就停止,不继续搜索其他索引
index-strategy = "first-index"

# unsafe-first-match:选择第一个索引中找到的第一个兼容版本
index-strategy = "unsafe-first-match"

# unsafe-best-match:跨所有索引选择最佳版本
index-strategy = "unsafe-best-match"

将包固定到特定索引

防止依赖混淆攻击,将内部包固定到私有索引:

[tool.uv.sources]
my-internal-pkg = { index = "private" }

tool.uv.index
name = "private"
url = "https://private.company.com/simple/"
# 明确声明此包只能从 private 索引获取
explicit = true

索引认证

tool.uv.index
name = "private"
url = "https://private.company.com/simple/"

通过环境变量传递凭证(不要写入配置文件):

# 用户名密码
export UV_INDEX_PRIVATE_USERNAME=myuser
export UV_INDEX_PRIVATE_PASSWORD=mypassword

# 或者 token(作为密码传入)
export UV_INDEX_PRIVATE_PASSWORD=mytoken

也可以在 URL 中嵌入(不推荐提交到版本控制):

tool.uv.index
name = "private"
url = "https://${MY_USER}:${MY_TOKEN}@private.company.com/simple/"

缓存管理

缓存策略

uv 对不同来源的依赖使用不同缓存策略:

依赖类型 缓存方式
PyPI 包 遵循 HTTP 缓存头(ETag / Last-Modified)
直接 URL HTTP 头 + URL 本身
Git 依赖 按解析后的 commit hash 缓存
本地路径 按文件修改时间缓存

缓存是线程安全的只追加的,支持多个 uv 进程并发使用同一缓存目录。

uv cache 命令

# 查看缓存占用大小
uv cache dir
du -sh $(uv cache dir)

# 清理所有缓存
uv cache clean

# 清理指定包的缓存
uv cache clean requests

# 删除未使用的缓存(精简)
uv cache prune

# CI 环境优化:删除预构建 wheel,保留从源码构建的 wheel
uv cache prune --ci

缓存强制刷新

# 重新验证所有包(忽略缓存)
uv sync --refresh

# 重新验证指定包
uv sync --refresh-package requests

# 完全不使用缓存
uv sync --no-cache

自定义缓存路径

# 通过环境变量
export UV_CACHE_DIR=/custom/cache/path

# 通过命令行
uv sync --cache-dir /custom/cache/path

自定义缓存键(动态依赖)

当项目依赖 C 扩展、Git 子模块或其他需要自定义缓存失效逻辑时:

[tool.uv]
cache-keys = [
    { file = "Cargo.toml" },          # Rust 扩展:Cargo.toml 变化时重建
    { file = "build.rs" },
    { git = true },                   # Git commit 变化时重建
    { env = "MY_BUILD_FLAG" },        # 环境变量变化时重建
]

配置文件

uv.toml vs pyproject.toml

配置文件 作用范围 适合场景
pyproject.toml 中的 [tool.uv] 单个项目 项目特定配置
uv.toml 项目级或全局级 单独管理 uv 配置,不混入 pyproject.toml
~/.config/uv/uv.toml 全局(用户级) 个人偏好设置

uv.toml 中不能包含 [project][tool.uv.workspace][tool.uv.sources] 等项目相关字段,这些必须在 pyproject.toml 中。

常用配置项

# uv.toml 或 pyproject.toml 中的 [tool.uv]

[tool.uv]
# Python 版本
python-preference = "managed"   # 优先使用 uv 管理的 Python
python-downloads = "automatic"  # 自动下载缺失的 Python 版本
# 可选:"manual"(手动下载)、"never"(不自动下载)

# 解析策略
resolution = "highest"          # 默认:选择最高兼容版本
# "lowest":选择最低兼容版本(用于检查依赖下限)
# "lowest-direct":直接依赖用最低,传递依赖用最高

# 链接模式(影响安装速度和磁盘使用)
link-mode = "clone"             # 默认:COW 克隆(支持的文件系统)
# "copy":完整复制(兼容性最好,但最慢)
# "hardlink":硬链接(快,但跨磁盘无效)
# "symlink":符号链接

# 预发布处理
prerelease = "disallow"         # 默认:不使用预发布版本
# "allow":允许预发布
# "if-necessary":仅在无稳定版时使用

# 构建隔离
no-build-isolation = false      # 默认隔离构建环境

# 并发限制
concurrent-downloads = 50       # 并发下载数
concurrent-builds = 16          # 并发构建数
concurrent-installs = 8         # 并发安装数

配置项查找优先级

命令行参数 > 环境变量 > 项目 pyproject.toml [tool.uv] >
项目 uv.toml > 父目录 uv.toml > 用户 ~/.config/uv/uv.toml

环境变量参考

常用环境变量:

环境变量 说明
UV_PYTHON 指定 Python 版本或路径
UV_PYTHON_DOWNLOADS 控制自动下载:automaticmanualnever
UV_PYTHON_INSTALL_DIR Python 安装目录
UV_PROJECT_ENVIRONMENT 虚拟环境路径(相对或绝对)
UV_INDEX_URL 主索引 URL(替换 PyPI)
UV_EXTRA_INDEX_URL 额外索引 URL
UV_DEFAULT_INDEX 默认索引名称
UV_INDEX_{NAME}_USERNAME 指定索引的用户名
UV_INDEX_{NAME}_PASSWORD 指定索引的密码/token
UV_CACHE_DIR 缓存目录路径
UV_NO_CACHE 设为 1 禁用缓存
UV_FROZEN 设为 1 相当于 --frozen
UV_LOCKED 设为 1 相当于 --locked
UV_NO_SYNC 设为 1 相当于 --no-sync
UV_DEV 设为 1 相当于 --dev
UV_NO_DEV 设为 1 相当于 --no-dev
UV_PUBLISH_TOKEN PyPI 发布 token
UV_PUBLISH_URL 发布目标 URL
UV_LINK_MODE 安装链接模式
UV_COMPILE_BYTECODE 设为 1 安装时编译 .pyc 文件
UV_BREAK_SYSTEM_PACKAGES 设为 1 允许修改系统 Python(CI/容器用)
UV_SYSTEM_PYTHON 设为 1 允许使用系统 Python
UV_TOOL_DIR 工具安装目录
UV_TOOL_BIN_DIR 工具二进制文件目录

uv export

uv.lock 导出为其他格式(如 requirements.txt)。

uv export [OPTIONS]
参数/选项 类型 默认值 说明
--format str requirements-txt 导出格式
--output-file / -o str stdout 输出文件
--no-dev flag 关闭 不包含开发依赖
--extra str - 包含指定可选依赖
--all-extras flag 关闭 包含所有可选依赖
--no-emit-project flag 关闭 不包含项目本身
--no-hashes flag 关闭 不生成哈希值
--frozen flag 关闭 不更新锁定文件
# 导出生产依赖(含哈希,安全部署)
uv export --no-dev -o requirements.txt

# 导出所有依赖(含开发)
uv export -o requirements-dev.txt

# 不含哈希
uv export --no-dev --no-hashes -o requirements.txt

# 导出可选依赖
uv export --extra docs -o requirements-docs.txt

Docker 集成

基础 Dockerfile

FROM python:3.12-slim

# 安装 uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# 设置工作目录
WORKDIR /app

# 先复制依赖声明文件(利用 Docker 层缓存)
COPY pyproject.toml uv.lock ./

# 安装依赖(不安装项目本身,充分利用层缓存)
RUN uv sync --frozen --no-install-project --no-dev

# 再复制项目代码
COPY . .

# 安装项目
RUN uv sync --frozen --no-dev

# 运行
CMD ["uv", "run", "python", "-m", "myapp"]

优化的多阶段 Dockerfile

FROM ghcr.io/astral-sh/uv:python3.12-bookworm-slim AS builder

WORKDIR /app

# 编译字节码(减少运行时启动时间)
ENV UV_COMPILE_BYTECODE=1
# 使用 copy 链接模式(容器跨文件系统)
ENV UV_LINK_MODE=copy

# 安装依赖(分层,利用 Docker 缓存)
RUN --mount=type=cache,target=/root/.cache/uv \
    --mount=type=bind,source=uv.lock,target=uv.lock \
    --mount=type=bind,source=pyproject.toml,target=pyproject.toml \
    uv sync --frozen --no-install-project --no-dev

# 复制代码并安装项目
COPY . .
RUN --mount=type=cache,target=/root/.cache/uv \
    uv sync --frozen --no-dev

FROM python:3.12-slim AS runtime

WORKDIR /app

# 从 builder 复制虚拟环境
COPY --from=builder /app/.venv /app/.venv

# 复制项目代码
COPY --from=builder /app /app

# 将虚拟环境加入 PATH
ENV PATH="/app/.venv/bin:$PATH"

CMD ["python", "-m", "myapp"]

.dockerignore

.venv
.git
__pycache__
*.pyc
*.egg-info
dist/
.pytest_cache/
.mypy_cache/
.ruff_cache/

安全审计

# 扫描依赖的已知漏洞(查询 OSV 数据库)
uv audit

# 只审计指定依赖组
uv audit --only-group test

# 排除 dev 依赖
uv audit --no-dev

# 审计指定 PEP 723 脚本
uv audit --script my_script.py

# 不更新锁定文件(CI 中使用)
uv audit --frozen

最佳实践

新项目启动

# 1. 初始化项目
uv init --lib my-project    # 库
uv init --app my-app        # 应用
cd my-project

# 2. 指定 Python 版本
uv python pin 3.12

# 3. 添加依赖
uv add fastapi pydantic sqlalchemy
uv add --dev pytest ruff mypy

# 4. 运行
uv run python -m myapp
uv run pytest

CI/CD 配置

# GitHub Actions 示例
- name: Install uv
  uses: astral-sh/setup-uv@v5
  with:
    version: "latest"
    enable-cache: true

- name: Install dependencies
  run: uv sync --frozen --all-extras

- name: Run tests
  run: uv run pytest --cov

- name: Type check
  run: uv run mypy src/

- name: Lint
  run: uv run ruff check .

关键原则:

  • CI 中始终使用 --frozen,确保使用锁定文件中的精确版本
  • 使用 astral-sh/setup-uv action 可以自动利用 GitHub Actions 缓存
  • uv.lock 必须提交到版本控制

生产部署

# 只安装生产依赖,精确同步
uv sync --frozen --no-dev --exact

# 或导出 requirements.txt 供部署使用
uv export --frozen --no-dev --no-hashes -o requirements.txt
pip install -r requirements.txt  # 在目标环境中

迁移现有 pip 项目

# 1. 初始化
uv init --bare  # 在已有项目目录

# 2. 从 requirements.txt 导入依赖
uv add $(cat requirements.txt | grep -v "^#" | tr "\n" " ")

# 或者保留 requirements.txt 格式
uv pip compile requirements.in -o requirements.txt

# 3. 验证
uv run python -c "import mymodule; print('OK')"

常见场景命令速查

场景 命令
初始化应用 uv init --app
初始化库 uv init --lib
添加依赖 uv add requests
添加开发依赖 uv add --dev pytest
删除依赖 uv remove requests
安装环境 uv sync
CI 安装 uv sync --frozen
升级所有依赖 uv lock --upgrade
运行脚本 uv run python main.py
临时运行工具 uvx ruff check .
安装全局工具 uv tool install ruff
安装 Python uv python install 3.12
导出 requirements uv export --no-dev -o requirements.txt
构建包 uv build
发布包 uv publish --token pypi-xxx
清理缓存 uv cache clean

踩坑与注意事项

1. uv.lock 不应手动编辑

uv.lock 是 uv 自动维护的文件,手动修改会导致解析状态不一致。需要修改依赖时,始终通过 uv adduv removeuv lock --upgrade-package 操作。

2. 工作区的 requires-python 取交集

工作区所有成员的 requires-python 取交集,如果某个成员要求 >=3.9,另一个要求 >=3.12,工作区的有效范围是 >=3.12。应在工作区根的 pyproject.toml 中声明最终的交集范围。

3. tool.uv.sources 不影响发布的包

[tool.uv.sources] 中的来源配置只在本地生效,发布到 PyPI 时会被忽略(这是预期行为)。发布前用 uv build --no-sources 构建以验证。

4. --frozen 和 --locked 的区别

  • --frozen:完全不更新 uv.lock,直接用现有版本安装。即使 pyproject.toml 有变化也忽略。
  • --locked:检查 uv.lock 是否与 pyproject.toml 一致,不一致则报错(不自动更新)。

CI 中推荐 --frozen,本地开发时如果不希望无意中更新锁定文件可用 --locked

5. dev 依赖组 vs optional-dependencies

特性 [dependency-groups] (--dev/--group) [project.optional-dependencies] (--optional)
是否发布到 PyPI 是(随包分发)
用途 本地开发、CI 可选功能供用户安装
安装命令 uv sync --group test uv sync --extra test

6. editable 安装的行为

工作区成员间依赖默认是可编辑的(editable)。路径依赖如果指定 editable = true,修改源码后无需重新安装即可生效。非可编辑的路径依赖修改后需要重新运行 uv sync

7. Python 版本自动下载

默认情况下(python-downloads = "automatic"),uv 会在需要时自动下载 Python 版本。如果在离线环境或不希望自动下载,设置:

export UV_PYTHON_DOWNLOADS=never
# 或
uv sync --no-managed-python

8. 依赖解析失败排查

# 查看详细解析过程
uv lock --verbose

# 查看依赖树
uv pip tree

# 检查特定包的依赖原因
uv pip tree --package requests

# 尝试最低版本解析(检查下界是否正确)
uv lock --resolution lowest

最佳实践

始终提交 uv.lock:lock 文件保证团队和 CI 使用完全相同的依赖版本树。将其纳入版本控制,并在 PR 中一并更新。

使用 uv add 而非手动编辑 pyproject.tomluv add 会同步更新 pyproject.tomluv.lock,手动编辑后必须运行 uv lock 才能同步锁文件,容易遗漏。

# 正确
uv add httpx

# 错误:手动改 pyproject.toml 后忘记 uv lock,导致 lock 文件与声明不一致
# 手动编辑 pyproject.toml...
# uv sync  # lock 文件未更新,与 pyproject 不一致

[tool.uv] 中固定 Python 版本:避免不同环境使用不同 Python 版本导致行为差异。

[tool.uv]
python = "3.12"

CI 中使用 uv sync --frozen--frozen 禁止 lock 文件更新,确保 CI 使用锁定版本,lock 文件若与 pyproject.toml 不一致则报错退出。

- name: Install deps
  run: uv sync --frozen

uvx 运行一次性工具,不污染项目依赖:对于 blackruffmypy 等仅在开发时使用的工具,用 uvx 直接运行而无需安装到项目虚拟环境。

uvx ruff check .
uvx black --check .

开发依赖用 uv add --dev:将测试、格式化、类型检查等工具声明为开发依赖,生产环境用 uv sync --no-dev 跳过安装。

uv add --dev pytest ruff mypy
# 生产部署
uv sync --no-dev

常见陷阱

陷阱:修改 pyproject.toml 后未重新生成 lock 文件

现象: uv sync 报错 "lock file is not consistent with pyproject.toml",或安装的版本与 pyproject.toml 声明不符。

原因: 手动编辑 pyproject.toml 不会自动更新 uv.lock,两者产生不一致。

解决: 使用 uv add / uv remove 修改依赖,或修改后立即运行 uv lock

# 修改 pyproject.toml 后必须执行
uv lock
uv sync

陷阱:缓存导致安装到旧版本

现象: 更新了版本约束,但 uv sync 后包版本未变化;或明明发布了新版本,uv 仍安装旧版本。

原因: uv 默认使用本地缓存(~/.cache/uv),缓存命中时不会重新下载。

解决: 清除缓存后重新同步。

uv cache clean
uv sync

陷阱:Workspace 中子包依赖解析冲突

现象: Workspace 根目录 uv lock 失败,提示某个子包要求的版本与其他子包冲突。

原因: Workspace 使用统一的 lock 文件,所有成员必须能共享同一个解析结果;子包之间的上界/下界约束互斥时无法解析。

解决: 放宽冲突包的版本约束,或在 [tool.uv] 中用 constraint-dependencies 固定中间版本。

# pyproject.toml (workspace root)
[tool.uv]
constraint-dependencies = ["pydantic>=2.0,<3"]

参见

阅读更多

Web 安全基础

1. HTML 转义(服务端渲染必须): 2. CSP(Content Security Policy): 3. HttpOnly Cookie:防止 JS 读取会话 Cookie: 4. 前端框架防护: 攻击者在第三方网站构造一个表单,诱导已登录用户提交,浏览器会自动携带目标站的 Cookie。 触发条件: 1. 用户已登录目标网站(Cookie 有效) 2. 目标 API 仅凭 Cookie 识别用户身份 3. 请求来源未验证 1. CSRF Token(推荐): 2. SameSite Cookie: 3. 验证 Origin/Referer 头:

By yellowdog

HTTP 协议深度指南

HTTP(HyperText Transfer Protocol)是 Web 的基础传输协议,基于 TCP/IP,采用请求/响应模型。 相关文档:Web安全基础(/web-an-quan-ji-chu/) FastAPI完全指南(/fastapi-wan-quan-zhi-nan/) Nginx完全指南(/nginx-wan-quan-zhi-nan/) 幂等性:多次执行相同请求,服务器状态结果相同。PUT /users/1 多次执行结果一致;POST /users 每次创建新资源,非幂等。 浏览器直接从本地缓存读取,不向服务器发送请求。 缓存命中时,状

By yellowdog

系统设计基础

SLA 对照表: 选择建议:无状态服务(Web 层、API 层)优先水平扩展;数据库初期垂直扩展,达到瓶颈后考虑分库分表或读写分离。 缓存穿透(查询不存在的 key,每次都打到 DB): 缓存击穿(热点 key 过期,瞬间大量请求打到 DB): 缓存雪崩(大量 key 同时过期,或缓存服务宕机): 令牌桶 Python 实现: Redis 实现分布式限流(滑动窗口): URL 命名规则: Cursor 分页响应格式: 雪花算法结构(64 bit): 定义:分布式系统不能同时满足以下三个特性: 在分布式环境中 P 是必须保证的,所以实际是 CP vs AP

By yellowdog

算法思路与模板

二分查找要求序列有序,每次将搜索范围缩减一半,时间复杂度 O(log n)。 两个指针从两端向中间收缩,常用于有序数组。 滑动窗口维护一个满足条件的区间 left, right,right 不断向右扩张,条件不满足时收缩 left。 滑动窗口通用框架: 1. 确定"子问题":原问题可以分解为哪些规模更小的同类问题 2. 定义 dpi 或 dpij 的含义,要足够清晰 3. 推导状态转移方程 4. 确定初始状态(边界条件) 5. 确定计算顺序(确保依赖的子问题先计算) 每件物品最多选一次。dpj = 容量为 j 时的最大价值,逆序遍历容量防止重复选取。 每

By yellowdog