跳到内容

管理依赖

依赖项字段

项目的依赖项在几个字段中定义

注意

即使项目不打算发布,也可以使用 project.dependenciesproject.optional-dependencies 字段。dependency-groups 是一项最近标准化的功能,可能尚未被所有工具支持。

uv 支持使用 uv adduv remove 修改项目的依赖项,但也可以通过直接编辑 pyproject.toml 来更新依赖项元数据。

添加依赖项

添加依赖项

$ uv add httpx

条目将被添加到 project.dependencies 字段中

pyproject.toml
[project]
name = "example"
version = "0.1.0"
dependencies = ["httpx>=0.27.2"]

可以使用 --dev--group--optional 标志将依赖项添加到其他字段。

依赖项将包含一个约束(例如 >=0.27.2)以获取包的最新兼容版本。可以通过 --bounds 调整绑定类型,或者直接提供约束

$ uv add "httpx>=0.20"

当从包注册表之外的来源添加依赖项时,uv 会在来源字段中添加一个条目。例如,从 GitHub 添加 httpx

$ uv add "httpx @ git+https://github.com/encode/httpx"

pyproject.toml 将包含一个 Git 来源条目

pyproject.toml
[project]
name = "example"
version = "0.1.0"
dependencies = [
    "httpx",
]

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }

如果依赖项无法使用,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 文件导入依赖项

使用 -r 选项可以将 requirements.txt 文件中声明的依赖项添加到项目中

uv add -r requirements.txt

有关详细信息,请参阅 pip 迁移指南

移除依赖项

移除依赖项

$ uv remove httpx

可以使用 --dev--group--optional 标志从特定表中移除依赖项。

如果为已移除的依赖项定义了 来源,并且没有该依赖项的其他引用,它也会被移除。

更改依赖项

更改现有依赖项(例如为 httpx 使用不同的约束)

$ uv add "httpx>0.1.0"

注意

在此示例中,我们正在更改 pyproject.toml 中依赖项的约束。只有在满足新约束需要时,才会更改依赖项的锁定版本。要强制将包版本更新到约束范围内的最新版本,请使用 --upgrade-package <name>,例如

$ uv add "httpx>0.1.0" --upgrade-package httpx

有关升级包的详细信息,请参阅 lockfile 文档。

请求不同的依赖项来源将更新 tool.uv.sources 表,例如在开发期间从本地路径使用 httpx

$ uv add "httpx @ ../httpx"

特定于平台的依赖项

要确保依赖项仅安装在特定平台或特定 Python 版本上,请使用 环境标记

例如,要在 Linux 上安装 jax,但在 Windows 或 macOS 上不安装

$ uv add "jax; sys_platform == 'linux'"

生成的 pyproject.toml 将在依赖项定义中包含环境标记

pyproject.toml
[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 表表示上传到 PyPI 或构建 wheel 时使用的依赖项。单个依赖项使用 依赖项说明符 语法指定,该表遵循 PEP 621 标准。

project.dependencies 定义了项目所需的包列表,以及安装它们时应使用的版本约束。每个条目都包含依赖项名称和版本。条目可以包含额外内容 (extras) 或特定于平台包的环境标记。例如

pyproject.toml
[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
  # See "Environment Markers" for more information
  "importlib_metadata >=7.1.0,<8; python_version < '3.10'",
  "mollymawk ==0.1.0"
]

依赖项来源

tool.uv.sources 表扩展了标准依赖项表,增加了开发期间使用的替代依赖项来源。

依赖项来源增加了对 project.dependencies 标准不支持的常见模式的支持,例如可编辑安装和相对路径。例如,要从相对于项目根目录的路径安装 foo

pyproject.toml
[project]
name = "example"
version = "0.1.0"
dependencies = ["foo"]

[tool.uv.sources]
foo = { path = "./packages/foo" }

uv 支持以下依赖项来源

  • 索引:从特定包索引解析的包。
  • Git:Git 仓库。
  • URL:远程 wheel 或源代码分发。
  • 路径:本地 wheel、源代码分发或项目目录。
  • 工作区:当前工作区的成员。

重要

来源仅被 uv 尊重。如果使用其他工具,则仅使用标准项目表中的定义。如果开发时使用其他工具,则需要以该工具的格式重新指定来源表中提供的任何元数据。

索引

要从特定索引添加 Python 包,请使用 --index 选项

$ uv add torch --index pytorch=https://download.pytorch.org/whl/cpu

uv 将把该索引存储在 [[tool.uv.index]] 中,并添加一个 [tool.uv.sources] 条目

pyproject.toml
[project]
dependencies = ["torch"]

[tool.uv.sources]
torch = { index = "pytorch" }

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

提示

由于 PyTorch 索引的特殊性,上述示例仅适用于 x86-64 Linux。有关设置 PyTorch 的更多信息,请参阅 PyTorch 指南

使用 index 来源会将包锁定到给定索引——它不会从其他索引下载。

定义索引时,可以包含 explicit 标志,以表明该索引应用于在 tool.uv.sources 中显式指定它的包。如果未设置 explicit,则如果在其他地方找不到包,可能会从该索引解析。

pyproject.toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cpu"
explicit = true

Git

要添加 Git 依赖项来源,请在 Git 兼容的 URL 前加上 git+

例如

$ # Install over HTTP(S).
$ uv add git+https://github.com/encode/httpx

$ # Install over SSH.
$ uv add git+ssh://[email protected]/encode/httpx
pyproject.toml
[project]
dependencies = ["httpx"]

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx" }

可以请求特定的 Git 引用,例如标签

$ uv add git+https://github.com/encode/httpx --tag 0.27.0
pyproject.toml
[project]
dependencies = ["httpx"]

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", tag = "0.27.0" }

或者,分支

$ uv add git+https://github.com/encode/httpx --branch main
pyproject.toml
[project]
dependencies = ["httpx"]

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", branch = "main" }

或者,修订版本(提交)

$ uv add git+https://github.com/encode/httpx --rev 326b9431c761e1ef1e00b9f760d1f654c8db48c6
pyproject.toml
[project]
dependencies = ["httpx"]

[tool.uv.sources]
httpx = { git = "https://github.com/encode/httpx", rev = "326b9431c761e1ef1e00b9f760d1f654c8db48c6" }

如果包不在仓库根目录中,可以指定 subdirectory

$ uv add git+https://github.com/langchain-ai/langchain#subdirectory=libs/langchain
pyproject.toml
[project]
dependencies = ["langchain"]

[tool.uv.sources]
langchain = { git = "https://github.com/langchain-ai/langchain", subdirectory = "libs/langchain" }

Git LFS 的支持也可以针对每个来源进行配置。默认情况下,不会获取 Git LFS 对象。

$ uv add --lfs git+https://github.com/astral-sh/lfs-cowsay
pyproject.toml
[project]
dependencies = ["lfs-cowsay"]

[tool.uv.sources]
lfs-cowsay = { git = "https://github.com/astral-sh/lfs-cowsay", lfs = true }
  • lfs = true 时,uv 将始终为此 Git 来源获取 LFS 对象。
  • lfs = false 时,uv 将永远不会为此 Git 来源获取 LFS 对象。
  • 省略时,UV_GIT_LFS 环境变量将用于所有没有显式 lfs 配置的 Git 来源。

重要

在尝试使用 Git LFS 安装来源之前,请确保系统上已安装并配置了 Git LFS,否则可能会导致构建失败。

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 包含

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 = <url> } 语法在 pyproject.toml 中手动添加或编辑。如果源代码分发不在归档根目录中,可以指定 subdirectory

路径

要添加路径来源,请提供 wheel(以 .whl 结尾)、源代码分发(通常以 .tar.gz.zip 结尾;所有支持的格式请参见 此处)或包含 pyproject.toml 的目录的路径。

例如

$ uv add /example/foo-0.1.0-py3-none-any.whl

将导致 pyproject.toml 包含

pyproject.toml
[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/

重要

当使用目录作为路径依赖项时,默认情况下 uv 会尝试将目标构建并安装为包。详细信息请参阅 虚拟依赖项 文档。

路径依赖项默认不使用 可编辑安装。可以为项目目录请求可编辑安装

$ uv add --editable ../projects/bar/

这将导致 pyproject.toml 包含

pyproject.toml
[project]
dependencies = ["bar"]

[tool.uv.sources]
bar = { path = "../projects/bar", editable = true }

提示

对于同一个仓库中的多个包,工作区 可能更合适。

工作区成员

要声明对工作区成员的依赖,请使用 { workspace = true } 添加成员名称。所有工作区成员都必须明确声明。工作区成员始终是 可编辑的。有关工作区的更多详细信息,请参阅 工作区 文档。

pyproject.toml
[project]
dependencies = ["foo==0.1.0"]

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

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

特定于平台的来源

通过为来源提供兼容 依赖项说明符 的环境标记,可以将来源限制为特定的平台或 Python 版本。

例如,要从 GitHub 拉取 httpx,但仅在 macOS 上,请使用以下内容

pyproject.toml
[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 标签

pyproject.toml
[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

pyproject.toml
[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 标志

$ uv lock --no-sources

使用 --no-sources 还会阻止 uv 发现任何可能满足给定依赖项的 工作区成员

可选依赖项

对于发布为库的项目,使某些功能变为可选以减少默认依赖树是很常见的。例如,Pandas 有一个 excel 额外功能 和一个 plot 额外功能,以避免在用户未明确要求的情况下安装 Excel 解析器和 matplotlib。额外功能通过 package[<extra>] 语法请求,例如 pandas[plot, excel]

可选依赖项在 [project.optional-dependencies] 中指定,这是一个将额外功能名称映射到其依赖项的 TOML 表,遵循 依赖项说明符 语法。

可选依赖项可以像普通依赖项一样在 tool.uv.sources 中拥有条目。

pyproject.toml
[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

注意

如果您有相互冲突的可选依赖项,除非您明确 声明它们为冲突,否则解析将失败。

来源也可以声明为仅适用于特定的可选依赖项。例如,根据可选的 cpugpu 额外功能从不同的 PyTorch 索引拉取 torch

pyproject.toml
[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 add --dev pytest

uv 使用 [dependency-groups] 表(如 PEP 735 中定义)来声明开发依赖项。上述命令将创建一个 dev

pyproject.toml
[dependency-groups]
dev = [
  "pytest >=8.1.1,<9"
]

dev 组是特殊处理的;有 --dev--only-dev--no-dev 标志来切换其依赖项的包含或排除。查看 --no-default-groups 以禁用所有默认组。此外,dev默认同步

依赖组

可以使用 --group 标志将开发依赖项分为多个组。

例如,在 lint 组中添加开发依赖项

$ uv add --group lint ruff

这会导致以下 [dependency-groups] 定义

pyproject.toml
[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 将解析项目需求失败并报错。

注意

如果您有相互冲突的依赖组,除非您明确 声明它们为冲突,否则解析将失败。

嵌套组

依赖组可以包含其他依赖组,例如

pyproject.toml
[dependency-groups]
dev = [
  {include-group = "lint"},
  {include-group = "test"}
]
lint = [
  "ruff"
]
test = [
  "pytest"
]

被包含组的依赖项不能与组中声明的其他依赖项冲突。

默认组

默认情况下,uv 会在环境中包含 dev 依赖组(例如在 uv runuv sync 期间)。要包含的默认组可以使用 tool.uv.default-groups 设置进行更改。

pyproject.toml
[tool.uv]
default-groups = ["dev", "foo"]

要默认启用所有依赖组,请使用 "all" 而不是列出组名

pyproject.toml
[tool.uv]
default-groups = "all"

提示

要在 uv runuv sync 期间禁用此行为,请使用 --no-default-groups。要排除特定的默认组,请使用 --no-group <name>

分组 requires-python

默认情况下,依赖组必须与项目的 requires-python 范围兼容。

如果依赖组需要的 Python 版本范围与项目不同,则可以在 [tool.uv.dependency-groups] 中为该组指定 requires-python,例如

pyproject.toml
[project]
name = "example"
version = "0.0.0"
requires-python = ">=3.10"

[dependency-groups]
dev = ["pytest"]

[tool.uv.dependency-groups]
dev = {requires-python = ">=3.12"}

旧版 dev-dependencies

[dependency-groups] 标准化之前,uv 使用 tool.uv.dev-dependencies 字段来指定开发依赖项,例如

pyproject.toml
[tool.uv]
dev-dependencies = [
  "pytest"
]

此部分中声明的依赖项将与 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 声明为构建依赖项

pyproject.toml
[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

pyproject.toml
[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 标志

$ uv add --editable ./path/foo

或者,要在工作区中选择不使用可编辑依赖项

$ uv add --no-editable ./path/foo

虚拟依赖项

uv 允许依赖项是“虚拟的”,在这种情况下,依赖项本身不会作为 安装,但它的依赖项会被安装。

默认情况下,依赖项绝不会是虚拟的。

具有 path 来源 的依赖项可以是虚拟的,如果它显式设置了 tool.uv.package = false。没有此设置时,uv 会将路径依赖项视为普通包并尝试构建它,即使项目未声明 构建系统

要将依赖项视为虚拟,请在来源上设置 package = false

pyproject.toml
[project]
dependencies = ["bar"]

[tool.uv.sources]
bar = { path = "../projects/bar", package = false }

如果依赖项设置了 tool.uv.package = false,可以通过在来源上声明 package = true 来覆盖它

pyproject.toml
[project]
dependencies = ["bar"]

[tool.uv.sources]
bar = { path = "../projects/bar", package = true }

类似地,具有 workspace 来源 的依赖项可以是虚拟的,如果它显式设置了 tool.uv.package = false。没有此设置时,即使未声明 构建系统,工作区成员也会被构建。

依赖项的工作区成员默认可以是虚拟的,例如,如果父级 pyproject.toml

pyproject.toml
[project]
name = "parent"
version = "1.0.0"
dependencies = []

[tool.uv.workspace]
members = ["child"]

并且子级 pyproject.toml 排除了构建系统

pyproject.toml
[project]
name = "child"
version = "1.0.0"
dependencies = ["anyio"]

那么 child 工作区成员将不会被安装,但传递依赖项 anyio 会被安装。

相反,如果父级声明了对 child 的依赖

pyproject.toml
[project]
name = "parent"
version = "1.0.0"
dependencies = ["child"]

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

[tool.uv.workspace]
members = ["child"]

那么 child 将被构建并安装。

依赖项说明符

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"

标记通过 andor 和括号组合,例如 aiohttp >=3.7.4,<4; (sys_platform != 'win32' or implementation_name != 'pypy') and python_version >= '3.10'。请注意,标记内的版本必须加引号,而标记的版本则绝对不能加引号。