跳转至

锁定环境

锁定(Locking)是指将一个依赖项(例如 ruff)及其要使用的确切版本写入文件。当处理多个依赖项时,锁定确切版本非常有用,可以确保环境能够被复现(reproduce)。如果不进行锁定,依赖项的版本可能会随时间推移、使用不同工具或跨平台而发生变化。

锁定依赖项

uv 允许以 requirements.txt 格式锁定依赖项。推荐使用标准的 pyproject.toml 来定义依赖项,但也支持其他依赖项格式。有关如何定义依赖项的更多详细信息,请参阅声明依赖项的文档。

要锁定 pyproject.toml 中声明的依赖项:

$ uv pip compile pyproject.toml -o requirements.txt

请注意,默认情况下 uv pip compile 的输出仅会显示在屏幕上,需要使用 --output-file / -o 参数才能写入文件。

要锁定 requirements.in 中声明的依赖项:

$ uv pip compile requirements.in -o requirements.txt

要锁定多个文件中声明的依赖项:

$ uv pip compile pyproject.toml requirements-dev.in -o requirements-dev.txt

uv 也支持传统的 setup.pysetup.cfg 格式。要锁定 setup.py 中声明的依赖项:

$ uv pip compile setup.py -o requirements.txt

要从标准输入锁定依赖项,使用 -

$ echo "ruff" | uv pip compile -

要在启用可选依赖项的情况下锁定,例如启用 "foo" extra:

$ uv pip compile pyproject.toml --extra foo

要在启用所有可选依赖项的情况下锁定:

$ uv pip compile pyproject.toml --all-extras

请注意,requirements.in 格式不支持 extras。

要锁定当前项目目录下 pyproject.toml 中的某个依赖项组(dependency group),例如组 foo

$ uv pip compile --group foo

Important

--group 标志需要添加到 pip-tools 的 pip compile 中,尽管他们正在考虑此事。我们期望支持他们最终采用的任何语法和语义。

要指定依赖项组应从哪个项目目录中获取:

$ uv pip compile --project some/path/ --group foo --group bar

或者,你可以为每个组指定一个 pyproject.toml 的路径:

$ uv pip compile --group some/path/pyproject.toml:foo --group other/pyproject.toml:bar

Note

--group 标志不会应用于其他指定的源文件。例如, uv pip compile some/path/pyproject.toml --group foo 会从 ./pyproject.toml 中获取 foo,而不是some/path/pyproject.toml 中获取。

升级依赖项

当使用输出文件时,uv 会考虑现有输出文件中已锁定的版本。如果某个依赖项已被锁定,则在后续的编译运行中不会被升级。例如:

$ echo "ruff==0.3.0" > requirements.txt
$ echo "ruff" | uv pip compile - -o requirements.txt
# This file was autogenerated by uv via the following command:
#    uv pip compile - -o requirements.txt
ruff==0.3.0

要升级某个依赖项,使用 --upgrade-package 标志:

$ uv pip compile - -o requirements.txt --upgrade-package ruff

要升级所有依赖项,可以使用 --upgrade 标志。

同步环境

可以直接从依赖项定义文件或编译后的 requirements.txt 文件中使用 uv pip install 安装依赖项。有关更多详细信息,请参阅从文件安装包的文档。

使用 uv pip install 安装时,已安装的包不会被移除,除非它们与锁定文件冲突。这意味着环境中可能存在锁定文件中未声明的依赖项,这对可复现性不利。要确保环境与锁定文件完全匹配,请改用 uv pip sync

要使用 requirements.txt 文件同步环境:

$ uv pip sync requirements.txt

要使用 PEP 751 格式的 pylock.toml 文件同步环境:

$ uv pip sync pylock.toml

添加约束

约束文件(constraints files)是类似于 requirements.txt 的文件,仅控制已安装依赖项的_版本_。然而,在约束文件中包含某个包_不会_触发该包的安装。约束可用于为不属于当前项目依赖项的依赖项添加版本边界。

要定义一个约束,为某个包定义一个版本边界:

constraints.txt
pydantic<2.0

要使用约束文件:

$ uv pip compile requirements.in --constraint constraints.txt

请注意,每个文件可以定义多个约束,也可以使用多个文件。

uv 还会从工作区根目录的 pyproject.toml 中读取 constraint-dependencies,并将其追加到约束文件中指定的那些约束之后。

添加构建约束

constraints 类似,但专门针对构建时依赖项(build-time dependencies),包括构建运行时依赖项时所需的依赖项。

构建约束文件是类似于 requirements.txt 的文件,仅控制构建时依赖项的_版本_。然而,在构建约束文件中包含某个包_不会_在构建时触发其安装;相反,约束仅在包被作为直接或传递性构建时依赖项需要时才会生效。构建约束可用于为未显式声明为当前项目构建时依赖项的依赖项添加版本边界。

例如,如果一个包定义了如下构建依赖项:

pyproject.toml
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

可以使用构建约束来确保工作区中的每个包都使用特定版本的 setuptools

build-constraints.txt
setuptools==75.0.0

uv 还会从工作区根目录的 pyproject.toml 中读取 build-constraint-dependencies,并将其追加到构建约束文件中指定的那些约束之后。

覆盖依赖项版本

覆盖文件(overrides files)是类似于 requirements.txt 的文件,强制安装某个依赖项的特定版本,无论任何组成包声明了什么要求,也无论这是否会被视为无效的解析结果。

约束是_叠加性_的,即它们与组成包的要求相结合;而覆盖是_绝对性_的,即它们完全替换组成包的要求。

覆盖最常用于移除传递性依赖项的上限版本边界。例如,如果 a 要求 c>=1.0,<2.0b 要求 c>=2.0,而当前项目同时要求 ab,则依赖项无法解析。

要定义一个覆盖,为有问题的包定义新的要求:

overrides.txt
c>=2.0

要使用覆盖文件:

$ uv pip compile requirements.in --override overrides.txt

现在,解析可以成功。然而,请注意,如果 a _确实_不支持 c>=2.0,那么在使用这些包时很可能会遇到运行时错误。

请注意,每个文件可以定义多个覆盖,也可以使用多个文件。