uv 项目依赖管理完全指南:从 pyproject.toml 字段到 tool.uv.sources 深度解析
uv 的"项目模式"(Project interface)以 pyproject.toml 为唯一事实来源,把依赖声明、版本锁定与环境同步统一在 uv add / uv remove / uv lock / uv sync 这条命令链中。本文围绕 uv 官方文档中的"Managing dependencies"主题,系统讲清四个核心字段(project.dependencies、project.optional-dependencies、dependency-groups、tool.uv.sources)的职责边界,逐一演示增删改依赖、环境标记、五类依赖源、extras、开发组、构建依赖、editable 与 virtual 依赖的完整用法,并结合 uv 仓库源码说明这些配置项在底层是如何被解析和校验的,帮助你在真实项目中建立可维护的依赖管理体系。
一、依赖声明的四个字段:职责边界
uv 中一个项目的依赖分布在 pyproject.toml 的多个字段中,各字段职责明确:
| 字段 | 用途 | 是否随包发布 |
|---|---|---|
project.dependencies |
发布的(published)依赖 | 是 |
project.optional-dependencies |
发布的可选依赖,即 extras | 是 |
[dependency-groups] |
本地开发依赖(遵循 PEP 735) | 否 |
[tool.uv.sources] |
开发期间的替代依赖源 | 否(uv 专用) |
两点重要前提:
project.dependencies与project.optional-dependencies即使项目不打算发布也可以使用;dependency-groups是近期标准化的特性(PEP 735),部分其他工具可能尚不支持。
uv 支持通过 uv add 和 uv remove 修改依赖,也可以直接编辑 pyproject.toml。
从源码结构看,这些字段的定义集中在 pyproject.rs 中:[tool.uv] 配置结构(ToolUvWorkspace 等)使用 serde 的 deny_unknown_fields 严格解析,tool.uv.workspace 表中的 members 与 exclude 均支持 glob 模式(如 libs/*),这解释了为什么工作区成员既可以用显式路径也可以用通配符声明。
二、添加依赖:uv add
基本用法
$ uv add httpx
会在 project.dependencies 中追加一条带版本约束的条目:
[project]
name = "example"
version = "0.1.0"
dependencies = ["httpx>=0.27.2"]
- 若加到别的字段,可用
--dev、--group <name>或--optional <extra>标志; - 默认约束是"最新兼容版本的最低下界",例如
>=0.27.2; - 约束的"边界类型"可用
--bounds调整(对应AddBoundsKind枚举,见 AddArgs:该选项处于 preview 阶段,语义为"若不提供约束或 URL,则按最新兼容版本生成下界约束;配合--frozen时不做解析、不加任何约束"); - 也可以直接给出约束:
uv add "httpx>=0.20"。
从非注册表来源添加时自动写入 sources
添加来自 Git 的 httpx:
$ uv add "httpx @ git+https://github.com/encode/httpx"
pyproject.toml 会生成一条 Git source 条目:
[project]
name = "example"
version = "0.1.0"
dependencies = [
"httpx",
]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }
这个"依赖表只保留名称、来源信息下沉到 tool.uv.sources"的行为是 uv 的默认策略。AddArgs 中的 --raw 选项(别名 --raw-sources)可以改变这一行为:提供 --raw 后,Git/本地/URL 等源要求会直接写进 project.dependencies,且默认不再附加版本下界(见 uv-cli/src/lib.rs)。
解析失败时的报错
当依赖无法满足时,uv 会给出推理链式错误:
$ uv add "httpx>9999"
× No solution found when resolving dependencies:
╰─▶ Because only httpx<=1.0.0b0 is available and your project depends on httpx>9999,
we can conclude that your project's requirements are unsatisfiable.
从 requirements 文件批量导入
requirements.txt 等文件中的依赖可通过 -r(别名 --requirement)一次性加入项目:
$ uv add -r requirements.txt
该选项支持的格式不限于 requirements.txt:还包含带内联元数据的 .py 文件、pylock.toml、pyproject.toml、setup.py 与 setup.cfg(见 AddArgs::requirements 的文档注释;源码中 RequirementsSource::PyprojectToml 在 uv add 场景下会被显式拒绝,见 add.rs 中的 bail 分支,即"从 pyproject.toml 导入"这一路径在 uv add 中有特殊限制)。更多迁移细节见 pip 到项目的迁移指南。
三、移除依赖:uv remove
$ uv remove httpx
--dev、--group、--optional可指定从哪个表移除;- 若被移除的依赖定义了 source,且不再有其他地方引用它,则该 source 条目会被一并清理。
四、修改依赖:改约束与改来源
修改版本约束
$ uv add "httpx>0.1.0"
注意:这条命令修改的是 pyproject.toml 中的约束,而已锁定(locked)的版本只在"必要"时才会变化。若想让包升级到新约束范围内的最新版,需显式指定:
$ uv add "httpx>0.1.0" --upgrade-package httpx
关于锁定版本升级策略,参见 锁文件文档。
修改依赖来源
把 httpx 改为从本地路径开发:
$ uv add "httpx @ ../httpx"
uv 会更新 tool.uv.sources 表。这一"约束与来源解耦"的设计正是后面 sources 机制的价值所在。
五、平台特定依赖:环境标记
要确保某依赖只在特定平台或特定 Python 版本下安装,使用 PEP 508 环境标记:
只装 Linux 的 jax:
$ uv add "jax; sys_platform == 'linux'"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["jax; sys_platform == 'linux'"]
只在 Python 3.11+ 安装 numpy:
$ uv add "numpy; python_version >= '3.11'"
完整的标记与运算符枚举见 Python 官方的环境标记文档。同理,依赖来源也可以按平台区分,见后文 平台特定来源。
六、project.dependencies:标准依赖字段
project.dependencies 表示上传 PyPI 或构建 wheel 时使用的依赖。每条依赖使用依赖说明符语法,整个表遵循 PEP 621 标准。每个条目包含依赖名与版本,可带 extras 或环境标记:
[project]
name = "albatross"
version = "0.1.0"
dependencies = [
# Any version in this range
"tqdm >=4.66.2,<5",
# Exactly this version of torch
"torch ==2.2.2",
# Install transformers with the torch extra
"transformers[torch] >=4.39.3,<5",
# Only install this package on older python versions
"importlib_metadata >=7.1.0,<8; python_version < '3.10'",
"mollymawk ==0.1.0"
]
七、依赖源 tool.uv.sources
tool.uv.sources 表为标准依赖表扩展了替代依赖源,仅在开发期间使用。它支持的正是标准 project.dependencies 表达不了的常见模式:editable 安装、相对路径等。例如从项目根的相对目录安装 foo:
[project]
name = "example"
version = "0.1.0"
dependencies = ["foo"]
[tool.uv.sources]
foo = { path = "./packages/foo" }
uv 支持的依赖源共五类:Index(特定包索引)、Git(Git 仓库)、URL(远程 wheel 或 sdist)、Path(本地 wheel/sdist/项目目录)、Workspace(当前工作区成员)。
重要:sources 只有 uv 会尊重。若使用其他工具,只有标准项目表中的定义会生效;如果开发依赖其他工具,sources 中的元数据必须用该工具的格式重新声明。
从源码看,这五类来源对应 Source 枚举 的五个变体:Git { git, subdirectory, path, rev, tag, branch, lfs, marker, extra, group }、Url { url, subdirectory, marker, extra, group }、Path { path, editable, package, marker, extra, group }、Registry { index, marker, extra, group }、Workspace { workspace, editable, marker, extra, group }。每个变体都携带可选的 marker/extra/group 字段——这正是"按平台/extras/依赖组限定来源"的底层能力;且 Source 声明了 deny_unknown_fields,写错键名会直接得到解析错误。
7.1 Index 源:绑定特定包索引
从特定索引添加包,使用 --index 选项(name=url 形式):
$ uv add torch --index pytorch=https://download.pytorch.org/whl/cpu
uv 会写入 [[tool.uv.index]] 并添加 [tool.uv.sources] 条目:
[project]
dependencies = ["torch"]
[tool.uv.sources]
torch = { index = "pytorch" }
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
若索引已配置好,可仅按名字选择(preview 功能):
$ uv add --preview-features index-by-name torch --index pytorch
上述示例只在 x86-64 Linux 上可用,这是 PyTorch 索引本身的特性;PyTorch 的完整配置见 PyTorch 集成指南。
关键语义:index 源会把包钉住(pin)到给定索引——它不会从其他索引下载。定义索引时可加 explicit 标志,表示该索引只用于在 tool.uv.sources 中显式指定它的包;若未设置 explicit,其他找不到的包也可能回落到该索引:
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
7.2 Git 源
Git 源要求 URL 前缀 git+,支持 HTTP(S) 与 SSH:
$ # Install over HTTP(S).
$ uv add git+https://github.com/encode/httpx
$ # Install over SSH.
$ uv add git+ssh://git@github.com/encode/httpx
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }
可指定具体的 Git 引用。tag:
$ uv add git+https://github.com/encode/httpx --tag 0.27.0
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", tag = "0.27.0" }
branch:
$ uv add git+https://github.com/encode/httpx --branch main
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", branch = "main" }
rev(commit):
$ uv add git+https://github.com/encode/httpx --rev 326b9431c761e1ef1e00b9f760d1f654c8db48c6
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", rev = "326b9431c761e1ef1e00b9f760d1f654c8db48c6" }
这三个引用选项在 CLI 中同属互斥的 git-ref 参数组(见 AddArgs),与源码中 Git 变体"rev / tag / branch 三选一、后续校验"的注释一致。
包不在仓库根目录时可指定 subdirectory:
$ uv add git+https://github.com/langchain-ai/langchain#subdirectory=libs/langchain
[project]
dependencies = ["langchain"]
[tool.uv.sources]
langchain = { git = "https://github.com/langchain-ai/langchain", subdirectory = "libs/langchain" }
Git LFS 可按源配置,默认不拉取 LFS 对象:
$ uv add --lfs git+https://github.com/astral-sh/lfs-cowsay
[project]
dependencies = ["lfs-cowsay"]
[tool.uv.sources]
lfs-cowsay = { git = "https://github.com/astral-sh/lfs-cowsay", lfs = true }
lfs = true:该 Git 源始终拉取 LFS 对象;lfs = false:该 Git 源从不拉取 LFS 对象;- 省略时:所有未显式配置
lfs的 Git 源统一由UV_GIT_LFS环境变量决定。
重要:使用 Git LFS 源之前,确保系统已安装并配置好 Git LFS,否则可能构建失败。
7.3 URL 源
提供 https:// 的 wheel(.whl)或源码发行版(通常 .tar.gz 或 .zip;支持的全部格式见 resolution 文档的 sdist 一节):
$ uv add "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz"
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz" }
URL 依赖也可以在 pyproject.toml 中用 { url = <url> } 手工添加或编辑。若 sdist 的包不在归档根部,可指定 subdirectory(对应源码 Url 变体的 subdirectory: Option<PortablePathBuf> 字段)。
7.4 Path 源
提供 wheel(.whl)、sdist(.tar.gz/.zip)路径,或包含 pyproject.toml 的目录路径:
$ uv add /example/foo-0.1.0-py3-none-any.whl
[project]
dependencies = ["foo"]
[tool.uv.sources]
foo = { path = "/example/foo-0.1.0-py3-none-any.whl" }
路径也可以是相对路径:
$ uv add ./foo-0.1.0-py3-none-any.whl
或者指向一个项目目录:
$ uv add ~/projects/bar/
重要:使用目录作为 path 依赖时,uv 默认会尝试构建并安装该目标为包。目录型 path 依赖默认不是 editable,需要显式请求:
$ uv add --editable ../projects/bar/
[project]
dependencies = ["bar"]
[tool.uv.sources]
bar = { path = "../projects/bar", editable = true }
若同一仓库内有多个包,workspaces 通常是更好的选择。
7.5 Workspace member 源
依赖工作区成员,用 { workspace = true } 声明成员名。所有工作区成员必须显式声明;工作区成员总是 editable,详见 workspace 文档。
从另一个工作区取源时,workspace 也可以是路径字符串:
[tool.uv.sources]
foo = { workspace = "../other-workspace" }
完整示例:
[project]
dependencies = ["foo==0.1.0"]
[tool.uv.sources]
foo = { workspace = true }
[tool.uv.workspace]
members = [
"packages/foo"
]
源码中 Workspace 变体的 workspace 字段类型为 WorkspaceReference 枚举(Bool 或 Path):true 选择当前工作区,路径字符串从给定路径发现另一个工作区;若为 false,该包则从远程索引获取而非作为工作区包包含进来。
7.6 平台特定 sources
给 source 加上依赖说明符兼容的环境标记,即可把来源限定到特定平台或 Python 版本。例如只在 macOS 上从 GitHub 拉 httpx:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", tag = "0.27.2", marker = "sys_platform == 'darwin'" }
标记写在了来源上而非依赖上,因此 uv 在所有平台都会安装 httpx,只是 macOS 上从 GitHub 下载,其他平台回落到 PyPI。
7.7 Multiple sources:按标记分流多个源
同一个依赖可以声明多个源,用 PEP 508 环境标记消歧。例如 macOS 与 Linux 分别拉不同 tag 的 httpx:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = [
{ git = "https://github.com/encode/httpx", tag = "0.27.2", marker = "sys_platform == 'darwin'" },
{ git = "https://github.com/encode/httpx", tag = "0.24.1", marker = "sys_platform == 'linux'" },
]
这一策略同样适用于按标记选择不同索引,例如按平台安装不同 PyTorch 索引的 torch:
[project]
dependencies = ["torch"]
[tool.uv.sources]
torch = [
{ index = "torch-cpu", marker = "platform_system == 'Darwin'"},
{ index = "torch-gpu", marker = "platform_system == 'Linux'"},
]
[[tool.uv.index]]
name = "torch-cpu"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
[[tool.uv.index]]
name = "torch-gpu"
url = "https://download.pytorch.org/whl/cu130"
explicit = true
源码对这种"多源列表"有严格的静态校验:Sources 的 TryFrom 实现 会遍历所有相邻源,对 extra 与 group 相同的两个源检查其标记是否不相交(disjoint)——若重叠则报 SourceError::OverlappingMarkers(并给出提示性的补集标记),同时要求列表非空(SourceError::EmptySources)。这解释了"多个来源必须用互斥标记消歧"这一硬性约束的来源。
7.8 禁用 sources
让 uv 忽略 tool.uv.sources(例如用包的发布元数据模拟解析):
$ uv lock --no-sources
--no-sources 同时会阻止 uv 发现本可满足该依赖的 workspace members。
源码层面,这一开关被建模为 NoSources 枚举:None(默认,使用 sources)、All(忽略所有包的 sources)、Packages(Vec<PackageName>)(只对指定包忽略),并提供 combine 组合语义(All 具有最高优先级)。也就是说 uv 还支持按包粒度禁用来源,比文档描述的"全开/全关"更细。
八、可选依赖(extras)
发布为库的项目常把部分功能做成可选,以减小默认依赖树。例如 Pandas 有 excel 与 plot 两个 extra,避免在未显式要求时安装 Excel 解析器与 matplotlib。extras 通过 package[<extra>] 语法请求,如 pandas[plot, excel]。
可选依赖定义在 [project.optional-dependencies] 表——从 extra 名到其依赖列表的映射,遵循依赖说明符语法;可选依赖与常规依赖一样可以在 tool.uv.sources 中有条目:
[project]
name = "pandas"
version = "1.0.0"
[project.optional-dependencies]
plot = [
"matplotlib>=3.6.3"
]
excel = [
"odfpy>=1.4.1",
"openpyxl>=3.1.0",
"python-calamine>=0.1.7",
"pyxlsb>=1.0.10",
"xlrd>=2.0.1",
"xlsxwriter>=3.0.5"
]
添加可选依赖使用 --optional <extra>:
$ uv add httpx --optional network
注意:若可选依赖之间互相冲突,除非你显式声明它们为冲突项,否则解析会失败。
来源也可以声明为仅对某个 extra 生效。例如按 cpu/gpu extra 从不同 PyTorch 索引安装 torch:
[project]
dependencies = []
[project.optional-dependencies]
cpu = [
"torch",
]
gpu = [
"torch",
]
[tool.uv.sources]
torch = [
{ index = "torch-cpu", extra = "cpu" },
{ index = "torch-gpu", extra = "gpu" },
]
[[tool.uv.index]]
name = "torch-cpu"
url = "https://download.pytorch.org/whl/cpu"
[[tool.uv.index]]
name = "torch-gpu"
url = "https://download.pytorch.org/whl/cu130"
这与源码中每个 Source 变体携带 extra: Option<ExtraName> 字段的定义一一对应。
九、开发依赖与 dependency groups
与可选依赖不同,开发依赖是本地专用的,发布到 PyPI 或其他索引时不会包含在项目元数据中,因此它们不在 [project] 表里,而是在 [dependency-groups] 表(PEP 735)中。开发依赖同样可以在 tool.uv.sources 中配置来源。
添加开发依赖使用 --dev:
$ uv add --dev pytest
该命令会创建 dev 组:
[dependency-groups]
dev = [
"pytest >=8.1.1,<9"
]
dev 组是被特殊对待的:有 --dev、--only-dev、--no-dev 三个标志来控制其包含/排除;而 --no-default-groups 可一次性禁用所有默认组。dev 组默认会被同步(见"默认组"一节)。在 CLI 源码中,--dev 被注释为 --group dev 的别名(见 AddArgs::dev)。
9.1 依赖组:--group
开发依赖可拆分为多个组,用 --group 指定。例如把 ruff 加入 lint 组:
$ uv add --group lint ruff
得到:
[dependency-groups]
dev = [
"pytest"
]
lint = [
"ruff"
]
定义组之后,--all-groups、--no-default-groups、--group、--only-group、--no-group 可用于包含或排除它们。
--dev、--only-dev、--no-dev分别等价于--group dev、--only-group dev、--no-group dev。
关键约束:uv 要求所有依赖组彼此兼容,创建锁文件时会一起解析所有组。若一个组里的依赖与另一个组不兼容,uv 会直接报错、解析失败:
注意:若依赖组之间互相冲突,除非显式声明为冲突组,否则解析会失败。
9.2 组嵌套:include-group
一个组可以包含其他组:
[dependency-groups]
dev = [
{include-group = "lint"},
{include-group = "test"}
]
lint = [
"ruff"
]
test = [
"pytest"
]
被包含组的依赖不能与所在组声明的其他依赖冲突。
9.3 默认组 default-groups
默认情况下,uv 在环境(如 uv run、uv sync)中包含 dev 组。用 tool.uv.default-groups 修改默认包含的组:
[tool.uv]
default-groups = ["dev", "foo"]
想默认启用所有组,用字符串 "all":
[tool.uv]
default-groups = "all"
想在
uv run/uv sync时禁用该行为,用--no-default-groups;想排除某个具体默认组,用--no-group <name>。
9.4 组级别的 requires-python
默认情况下,依赖组必须与项目的 requires-python 区间兼容。若某个组需要不同的 Python 版本范围,可在 [tool.uv.dependency-groups] 中为组单独指定:
[project]
name = "example"
version = "0.0.0"
requires-python = ">=3.10"
[dependency-groups]
dev = ["pytest"]
[tool.uv.dependency-groups]
dev = {requires-python = ">=3.12"}
9.5 遗留字段 tool.uv.dev-dependencies
在 [dependency-groups] 标准化之前,uv 使用 tool.uv.dev-dependencies 声明开发依赖:
[tool.uv]
dev-dependencies = [
"pytest"
]
该字段中的依赖会与 dependency-groups.dev 的内容合并,未来会被弃用移除。
注意:若
tool.uv.dev-dependencies字段存在,uv add --dev会沿用既有章节,而不是新建dependency-groups.dev章节。
十、构建依赖(Build dependencies)
若项目是一个 Python 包,它可以声明构建所需但运行不需要的依赖,写在 [build-system].requires 中(PEP 518)。例如使用 setuptools 作为构建后端:
[project]
name = "pandas"
version = "0.1.0"
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
默认情况下 uv 在解析构建依赖时也会尊重 tool.uv.sources。例如让构建使用本地的 setuptools:
[project]
name = "pandas"
version = "0.1.0"
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
[tool.uv.sources]
setuptools = { path = "./packages/setuptools" }
发布包时建议运行 uv build --no-sources 验证,确保在禁用 tool.uv.sources 的情况下(如同 pypa/build 等构建工具的场景)包仍能正确构建。
十一、Editable 依赖
普通安装一个含 Python 包的目录时,流程是"先构建 wheel,再把 wheel 装进虚拟环境",会拷贝全部源码;之后源码再被修改,虚拟环境里就是过期版本。editable 安装通过在虚拟环境中放置一个指向项目的 .pth 文件来解决问题,让解释器直接包含源码文件。
editable 有一些限制(主要是构建后端需支持、原生模块在 import 前不会重新编译),但开发场景下非常有用:虚拟环境始终使用包的最新改动。uv 对工作区包默认使用 editable 安装。
添加 editable 依赖:
$ uv add --editable ./path/foo
对工作区依赖反向退出 editable:
$ uv add --no-editable ./path/foo
CLI 层面 --editable / --no-editable 构成互相覆盖(overrides_with)的标志对,且 uv add 还有按包粒度的隐藏选项 --no-editable-package(见 AddArgs)。
十二、Virtual 依赖
uv 允许依赖是"虚拟"的:依赖本身不作为一个 包 安装,但它的依赖会被安装。默认情况下依赖从不是虚拟的。
- path 源:只有当依赖显式设置
tool.uv.package = false时才虚拟。没有该设置时,uv 把 path 依赖当普通包处理并尝试构建它——即使该目录未声明构建系统。
[project]
dependencies = ["bar"]
[tool.uv.sources]
bar = { path = "../projects/bar", package = false }
若依赖侧设置了 tool.uv.package = false,可在来源上以 package = true 覆盖:
[project]
dependencies = ["bar"]
[tool.uv.sources]
bar = { path = "../projects/bar", package = true }
这与源码中 Path 变体 package 字段的注释一致:"若为 false,包不会被构建或安装,但其依赖会进入虚拟环境;省略时依据项目 pyproject.toml 中是否存在 [build-system] 推断"(见 Source::Path)。
- workspace 源:同理,workspace 成员只有显式
tool.uv.package = false时才虚拟;未设置时,即使未声明构建系统,成员也会被构建。
不是依赖的 workspace 成员可以默认为虚拟。例如父项目:
[project]
name = "parent"
version = "1.0.0"
dependencies = []
[tool.uv.workspace]
members = ["child"]
子项目未声明构建系统:
[project]
name = "child"
version = "1.0.0"
dependencies = ["anyio"]
则 child 本身不会被安装,但其传递依赖 anyio 会。
反之,若父项目声明了对 child 的依赖:
[project]
name = "parent"
version = "1.0.0"
dependencies = ["child"]
[tool.uv.sources]
child = { workspace = true }
[tool.uv.workspace]
members = ["child"]
则 child 会被构建并安装。
十三、依赖说明符(Dependency specifiers)
uv 使用标准的依赖说明符,最初由 PEP 508 定义。说明符按顺序由以下部分构成:
- 依赖名;
- 想要的 extras(可选);
- 版本说明符;
- 环境标记(可选)。
要点:
- 版本说明符以逗号分隔、累加语义:
foo >=1.2.3,<2,!=1.4.0表示"至少 1.2.3、小于 2、且不是 1.4.0 的foo版本"; - 说明符按需补零:
foo ==2也能匹配 2.0.0; - 等号末位可用星号:
foo ==2.1.*接受 2.1 系列的所有发布; ~=表示"末位相等或更高":foo ~=1.2等价于foo >=1.2,<2;foo ~=1.2.3等价于foo >=1.2.3,<1.3;- extras 用方括号、逗号分隔、位于名称与版本之间:
pandas[excel,plot] ==2.2,extra 名之间空白被忽略; - 标记用于特定环境的依赖,例如为
importlib.metadata模块装旧版 backport:importlib-metadata >=7.1.0,<8; python_version < '3.10';只在 Windows 装colorama:colorama >=0.4.6,<5; platform_system == "Windows"; - 标记可用
and、or与括号组合,如aiohttp >=3.7.4,<4; (sys_platform != 'win32' or implementation_name != 'pypy') and python_version >= '3.10'; - 易错点:标记内部的版本必须加引号,标记外部的版本不得加引号。
十四、小结:一条完整的依赖管理心智模型
- 声明:发布依赖进
project.dependencies,可选功能进project.optional-dependencies,开发工具进[dependency-groups]; - 换源:Git/URL/本地路径/workspace/特定索引等开发期来源统一进
[tool.uv.sources],并可用marker、extra、group三元组精确限定生效范围,多来源必须互斥标记; - 命令:
uv add(支持--dev/--group/--optional/--index/--tag/--branch/--rev/--lfs/--editable/--bounds/-r等)与uv remove完成声明变更并自动重新锁定与同步; - 逃生舱:
--no-sources/--no-editable用于模拟"脱离本地源"的发布语义,package = false用于只取依赖树不装本体。
uv 的这套设计把"标准可发布元数据"与"开发期灵活性"分离:前者是任何工具都能读懂的 PEP 标准字段,后者集中在 uv 私有的 tool.uv 命名空间下,源码层面通过 Source 枚举 与 Sources 校验逻辑 保证配置的结构正确性与标记互斥性,这也是 uv.lock 能跨开发机稳定复现的基础。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00