管理依赖项
依赖项字段
项目的依赖项在以下几个字段中定义:
- project.dependencies
:发布的依赖项。
- project.optional-dependencies
:发布的可选依赖项,即 “额外项”。
- dependency-groups
:用于开发的本地依赖项。
- tool.uv.sources
:开发期间依赖项的替代源。
注意
即使项目不打算发布,也可以使用 project.dependencies
和 project.optional-dependencies
字段。dependency-groups
是最近标准化的功能,可能并非所有工具都支持。
uv 支持使用 uv add
和 uv remove
修改项目的依赖项,但也可以通过直接编辑 pyproject.toml
更新依赖项元数据。
添加依赖项
要添加依赖项:
会在 project.dependencies
字段中添加一项:
可以使用 --dev
、--group
或 --optional
标志将依赖项添加到其他字段。
依赖项将包含一个约束,例如 >=0.27.2
,表示该软件包的最新兼容版本。也可以提供其他约束:
从软件包注册表以外的来源添加依赖项时,uv 会在 sources
字段中添加一项。例如,从 GitHub 添加 httpx
时:
pyproject.toml
将包含一个 Git 源条目:
[project]
name = "example"
version = "0.1.0"
dependencies = [
"httpx",
]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }
如果某个依赖项不可用,uv 将显示错误:
$ uv add "httpx>9999"
× 解析依赖项时未找到解决方案:
╰─▶ 因为只有 `httpx<=1.0.0b0` 可用,而您的项目依赖于 `httpx>9999`,
所以我们可以得出结论,您项目的需求无法满足。
导入依赖项
可以使用 -r
选项将 requirements.txt
文件中声明的依赖项添加到项目中:
删除依赖项
要删除依赖项:
可以使用 --dev
、--group
或 --optional
标志从特定表中删除依赖项。
如果为要删除的依赖项定义了 源,并且没有其他对该依赖项的引用,那么该源也将被删除。
更改依赖项
要更改现有依赖项,例如,为 httpx
使用不同的约束条件:
注意
在这个示例中,我们正在更改 pyproject.toml
中依赖项的约束条件。
只有在必要时,为满足新的约束条件,依赖项的锁定版本才会更改。要强制将包版本更新为约束范围内的最新版本,请使用 --upgrade-package <name>
,例如:
有关升级包的更多详细信息,请参阅 锁定文件 文档。
请求不同的依赖源将更新 tool.uv.sources
表,例如,在开发期间从本地路径使用 httpx
:
特定平台的依赖项
为确保依赖项仅安装在特定平台或特定 Python 版本上,请使用 环境标记。
例如,要在 Linux 上安装 jax
,但不在 Windows 或 macOS 上安装:
生成的 pyproject.toml
将在依赖项定义中包含环境标记:
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["jax; sys_platform == 'linux'"]
同样,要在 Python 3.11 及更高版本中包含 numpy
:
有关可用标记和运算符的完整列表,请参阅 Python 的 环境标记 文档。
提示
依赖源也可以按平台更改。
项目依赖
project.dependencies
表表示上传到 PyPI 或构建 wheel 时使用的依赖项。单个依赖项使用 依赖说明符 语法指定,并且该表遵循 PEP 621 标准。
project.dependencies
定义了项目所需的包列表,以及安装这些包时应使用的版本约束。每个条目都包含一个依赖项名称和版本。条目可能包含特定于平台的包的额外功能或环境标记。例如:
[project]
name = "albatross"
version = "0.1.0"
dependencies = [
# 此范围内的任何版本
"tqdm >=4.66.2,<5",
# 完全是此版本的 torch
"torch ==2.2.2",
# 安装带有 torch 额外功能的 transformers
"transformers[torch] >=4.39.3,<5",
# 仅在较旧的 Python 版本上安装此包
# 有关更多信息,请参阅“环境标记”
"importlib_metadata >=7.1.0,<8; python_version < '3.10'",
"mollymawk ==0.1.0"
]
依赖源
tool.uv.sources
表使用替代依赖源扩展了标准依赖表,这些替代依赖源用于开发过程。
依赖源为 project.dependencies
标准不支持的常见模式提供支持,例如可编辑安装和相对路径。例如,从相对于项目根目录的目录安装 foo
:
[project]
name = "example"
version = "0.1.0"
dependencies = ["foo"]
[tool.uv.sources]
foo = { path = "./packages/foo" }
uv 支持以下依赖源: - 索引:从特定包索引解析的包。 - Git:一个 Git 仓库。 - URL:远程 wheel 或源发行版。 - 路径:本地 wheel、源发行版或项目目录。 - 工作区:当前工作区的成员。
Important
源仅对 uv 有效。如果使用其他工具,则仅会使用标准项目表中的定义。如果使用其他工具进行开发,则需要以其他工具的格式重新指定源表中提供的任何元数据。
索引
要从特定索引添加 Python 包,请使用 --index
选项:
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"
Tip
由于 PyTorch 索引的特殊性,上述示例仅在 x86-64 Linux 上有效。 有关设置 PyTorch 的更多信息,请参阅 PyTorch 指南。
使用 index
源将包 固定 到给定的索引 —— 它不会从其他索引下载。
定义索引时,可以包含 explicit
标志,以指示该索引 仅 应用于在 tool.uv.sources
中显式指定它的包。如果未设置 explicit
,其他包在其他地方找不到时,可能会从该索引解析。
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true
Git
要添加一个 Git 依赖源,在兼容 Git 的 URL(即你使用 git clone
时所用的 URL)前加上 git+
。
例如:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }
可以指定特定的 Git 引用,例如标签:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", tag = "0.27.0" }
或者,分支:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", branch = "main" }
或者,版本(提交):
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", rev = "326b9431c761e1ef1e00b9f760d1f654c8db48c6" }
如果包不在仓库根目录,可以指定 subdirectory
:
[project]
dependencies = ["langchain"]
[tool.uv.sources]
langchain = { git = "https://github.com/langchain-ai/langchain", subdirectory = "libs/langchain" }
URL
要添加 URL 源,请提供指向 wheel 文件(以 .whl
结尾)或源分发包(通常以 .tar.gz
或 .zip
结尾;有关所有支持的格式,请参阅此处)的 https://
URL。
例如:
$ uv add "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz"
这将生成一个 pyproject.toml
文件,内容如下:
[project]
dependencies = ["httpx"]
[tool.uv.sources]
httpx = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz" }
也可以使用 { url = <url> }
语法在 pyproject.toml
中手动添加或编辑 URL 依赖项。如果源分发包不在归档文件的根目录中,可以指定 subdirectory
。
路径
要添加路径源,请提供 wheel 文件(以 .whl
结尾)、源发行版(通常以 .tar.gz
或 .zip
结尾;有关所有支持的格式,请参阅此处)的路径,或包含 pyproject.toml
的目录的路径。
例如:
这将生成一个 pyproject.toml
文件,内容如下:
[project]
dependencies = ["foo"]
[tool.uv.sources]
foo = { path = "/example/foo-0.1.0-py3-none-any.whl" }
路径也可以是相对路径:
或者,是项目目录的路径:
重要
默认情况下,路径依赖不会使用可编辑安装。对于项目目录,可以请求进行可编辑安装:
这将生成一个 pyproject.toml
文件,内容如下:
[project]
dependencies = ["bar"]
[tool.uv.sources]
bar = { path = "../projects/bar", editable = true }
同样,如果一个项目被标记为非包,但你希望在环境中将其作为包安装,则在源上设置 package = true
:
[project]
dependencies = ["bar"]
[tool.uv.sources]
bar = { path = "../projects/bar", package = true }
对于同一存储库中的多个包,工作区可能更合适。
工作区成员
要声明对工作区成员的依赖,添加带有 { workspace = true }
的成员名称。所有工作区成员都必须明确声明。工作区成员始终是可编辑的。有关工作区的更多详细信息,请参阅工作区文档。
[project]
dependencies = ["foo==0.1.0"]
[tool.uv.sources]
foo = { workspace = true }
[tool.uv.workspace]
members = [
"packages/foo"
]
特定平台的源
你可以通过为源提供与依赖说明符兼容的环境标记,将源限制在特定平台或 Python 版本。
例如,要从 GitHub 拉取 httpx
,但仅在 macOS 上拉取,可使用以下配置:
[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。
多个源
你可以通过提供源列表,为单个依赖指定多个源,并使用与 PEP 508 兼容的环境标记来区分。
例如,在 macOS 和 Linux 上拉取不同的 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/cu124"
explicit = true
禁用源
要指示 uv 忽略 tool.uv.sources
表(例如,模拟使用包的已发布元数据进行解析),请使用 --no-sources
标志:
使用 --no-sources
还会阻止 uv 发现任何可以满足给定依赖的 工作区成员。
可选依赖项
对于作为库发布的项目而言,将某些功能设为可选,以减少默认依赖树,这是很常见的做法。例如,Pandas 有一个excel
额外功能和一个plot
额外功能,这样除非有人明确要求,否则不会安装 Excel 解析器和 matplotlib
。使用 package[<extra>]
语法来请求额外功能,例如 pandas[plot, excel]
。
可选依赖项在 [project.optional-dependencies]
中指定,这是一个 TOML 表,按照依赖说明符语法,将额外功能名称映射到其依赖项。
可选依赖项可以像普通依赖项一样在 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>
选项:
注意
如果您的可选依赖项相互冲突,除非您明确将它们声明为冲突项,否则解析将会失败。
源也可以声明为仅适用于特定的可选依赖项。例如,根据可选的 cpu
或 gpu
额外功能,从不同的 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/cu124"
开发依赖项
与可选依赖项不同,开发依赖项仅在本地使用,发布到 PyPI 或其他索引时,不会包含在项目需求中。因此,开发依赖项不包含在 [project]
表中。
开发依赖项可以像普通依赖项一样在 tool.uv.sources
中有相应条目。
要添加开发依赖项,请使用 --dev
标志:
uv 使用 [dependency-groups]
表(如 PEP 735 中所定义)来声明开发依赖项。上述命令将创建一个 dev
组:
dev
组是特殊情况;有 --dev
、--only-dev
和 --no-dev
标志来切换是否包含其依赖项。若要禁用所有默认组,请参阅 --no-default-groups
。此外,dev
组默认同步。
依赖组
使用 --group
标志,开发依赖可以划分为多个组。
例如,要在 lint
组中添加一个开发依赖:
这将生成以下 [dependency-groups]
定义:
定义好组后,可以使用 --all-groups
、--no-default-groups
、--group
、--only-group
和 --no-group
选项来包含或排除它们的依赖项。
Tip
--dev
、--only-dev
和 --no-dev
标志分别等同于 --group dev
、--only-group dev
和 --no-group dev
。
uv 要求所有依赖组相互兼容,并且在创建锁定文件时会一起解析所有组。
如果一个组中声明的依赖与另一个组中的依赖不兼容,uv 将无法解析项目需求并报错。
Note
如果有相互冲突的依赖组,除非你明确声明它们冲突,否则解析将会失败。
默认组
默认情况下,uv 在环境中包含 dev
依赖组(例如,在 uv run
或 uv sync
期间)。可以使用 tool.uv.default-groups
设置更改要包含的默认组。
要默认启用所有依赖组,可以使用 "all"
而不是列出组名:
Tip
要在 uv run
或 uv sync
期间禁用此行为,可以使用 --no-default-groups
。
要排除特定的默认组,可以使用 --no-group <name>
。
旧版 dev-dependencies
在 [dependency-groups]
标准化之前,uv 使用 tool.uv.dev-dependencies
字段来指定开发依赖项,例如:
在此部分声明的依赖项将与 dependency-groups.dev
中的内容合并。最终,dev-dependencies
字段将被弃用并移除。
注意
如果存在 tool.uv.dev-dependencies
字段,uv add --dev
将使用现有部分,而不是添加新的 dependency-groups.dev
部分。
构建依赖项
如果项目按照 Python 包 结构组织,它可能会声明构建项目所需但运行项目不需要的依赖项。这些依赖项在 [build-system]
表的 build-system.requires
下指定,遵循 PEP 518。
例如,如果一个项目使用 setuptools
作为其构建后端,它应该将 setuptools
声明为构建依赖项:
[project]
name = "pandas"
version = "0.1.0"
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
默认情况下,uv 在解析构建依赖项时会遵循 tool.uv.sources
。例如,要使用本地版本的 setuptools
进行构建,将源添加到 tool.uv.sources
:
[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
)时的情况一样。
可编辑依赖项
常规安装包含 Python 包的目录时,首先会构建一个 wheel 文件,然后将该 wheel 文件安装到虚拟环境中,并复制所有源文件。当包源文件被编辑后,虚拟环境中仍会包含旧版本。
可编辑安装通过在虚拟环境中添加指向项目的链接(一个 .pth
文件)来解决此问题,该链接指示解释器直接包含源文件。
可编辑安装存在一些限制(主要是:构建后端需要支持它们,并且原生模块在导入前不会重新编译),但它们对开发很有用,因为虚拟环境将始终使用包的最新更改。
uv 默认对工作区包使用可编辑安装。
要添加可编辑依赖项,请使用 --editable
标志:
或者,要在工作区中选择不使用可编辑依赖项:
依赖说明符(PEP 508)
uv 使用依赖说明符,以前称为PEP 508。一个依赖说明符按顺序由以下部分组成:
- 依赖名称
- 所需的额外功能(可选)
- 版本说明符
- 环境标记(可选)
版本说明符以逗号分隔并组合在一起,例如,foo >=1.2.3,<2,!=1.4.0
被解释为 “foo
的版本至少为 1.2.3,但小于 2,且不是 1.4.0”。
如有需要,说明符会用尾随零填充,因此 foo ==2
也匹配 foo 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
。
额外功能在名称和版本之间的方括号内以逗号分隔,例如,pandas[excel,plot] ==2.2
。额外功能名称之间的空白会被忽略。
有些依赖仅在特定环境中才需要,例如特定的 Python 版本或操作系统。例如,要为 importlib.metadata
模块安装 importlib-metadata
回退版本,使用 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'
。请注意,标记内的版本必须加引号,而标记外的版本不能加引号。