解析
解析是将需求列表转换为满足这些需求的包版本列表的过程。解析需要递归地搜索包的兼容版本,确保所请求的需求得到满足,且所请求包的依赖项也是兼容的。
依赖项
大多数项目和包都有依赖项。依赖项是当前包正常工作所必需的其他包。包将其依赖项定义为“需求”,通常是包名称和可接受版本的组合。由当前项目定义的依赖项称为“直接依赖项”。由当前项目的每个依赖项所添加的依赖项称为“间接”或“传递”依赖项。
注意
有关依赖项的详细信息,请参阅 Python 打包文档中的依赖说明符页面。
基本示例
为了演示解析过程,请考虑以下依赖项
- 项目依赖于
foo和bar。 foo有一个版本:1.0.0foo 1.0.0依赖于lib>=1.0.0。
bar有一个版本:1.0.0bar 1.0.0依赖于lib>=2.0.0。
lib有两个版本:1.0.0 和 2.0.0。这两个版本都没有依赖项。
在此示例中,解析器必须找到一组满足项目需求的包版本。由于 foo 和 bar 都只有一个版本,因此将使用这些版本。解析还必须包含传递依赖项,因此必须选择一个 lib 版本。foo 1.0.0 允许使用所有可用的 lib 版本,但 bar 1.0.0 要求 lib>=2.0.0,因此必须使用 lib 2.0.0。
在某些解析中,可能存在多个有效的解决方案。请考虑以下依赖项
- 项目依赖于
foo和bar。 foo有两个版本:1.0.0 和 2.0.0foo 1.0.0没有依赖项。foo 2.0.0依赖于lib==2.0.0。
bar有两个版本:1.0.0 和 2.0.0bar 1.0.0没有依赖项。bar 2.0.0依赖于lib==1.0.0
lib有两个版本:1.0.0 和 2.0.0。这两个版本都没有依赖项。
在此示例中,必须选择 foo 和 bar 的某个版本;然而,确定哪个版本需要考虑 foo 和 bar 每个版本的依赖项。foo 2.0.0 和 bar 2.0.0 不能同时安装,因为它们对所需的 lib 版本存在冲突,因此解析器必须选择 foo 1.0.0(连同 bar 2.0.0)或 bar 1.0.0(连同 foo 2.0.0)。两者都是有效的解决方案,不同的解析算法可能会产生任一结果。
平台标记
标记允许将表达式附加到需求,以指示何时应使用该依赖项。例如 bar ; python_version < "3.9" 表示 bar 仅应安装在 Python 3.8 及更早版本上。
标记用于根据当前环境或平台调整包的依赖项。例如,标记可用于根据操作系统、CPU 架构、Python 版本、Python 实现等修改依赖项。
注意
有关标记的更多详细信息,请参阅 Python 打包文档中的环境标记部分。
标记对于解析非常重要,因为它们的值会改变所需的依赖项。通常,Python 包解析器会使用“当前”平台的标记来确定要使用哪些依赖项,因为包通常是“安装”在当前平台上的。但是,对于“锁定”依赖项,这会带来问题——锁文件仅适用于使用与创建锁文件时相同平台的开发人员。为了解决这个问题,存在平台无关或“通用”解析器。
特定于平台的解析
默认情况下,uv 的 pip 接口(即 uv pip compile)产生的解析是特定于平台的,就像 pip-tools 一样。在 uv 的项目接口中无法使用特定于平台的解析。
uv 还支持通过 --python-platform 和 --python-version 选项为特定的备选平台和 Python 版本进行解析。例如,如果要在 macOS 上使用 Python 3.12,则可以使用 uv pip compile --python-platform linux --python-version 3.10 requirements.in 来生成 Linux 上 Python 3.10 的解析结果。与通用解析不同,在特定于平台的解析过程中,提供的 --python-version 是要使用的确切 Python 版本,而不是下限。
注意
Python 的环境标记暴露了关于当前机器的远比简单的 --python-platform 参数所能表达的信息。例如,macOS 上的 platform_version 标记包含了内核构建的时间,理论上可以将其编码在包需求中。uv 的解析器会尽最大努力生成与在目标 --python-platform 上运行的任何机器兼容的解析结果,这对于大多数用例来说应该足够了,但对于复杂的包和平台组合,可能会损失一些保真度。
通用解析
uv 的锁文件 (uv.lock) 是通过通用解析创建的,并且可以在不同平台间移植。这确保了无论操作系统、架构和 Python 版本如何,所有在项目上工作的人的依赖项都是锁定的。uv 锁文件由 项目 命令(如 uv lock、uv sync 和 uv add)创建和修改。
通用解析在 uv 的 pip 接口(即 uv pip compile)中也可用,使用 --universal 标志。生成的需求文件将包含标记,以指示每个依赖项适用于哪个平台。
在通用解析期间,如果不同平台需要不同版本的包,则同一个包可能会在锁文件中被多次列出,并带有不同的版本或 URL——标记决定了将使用哪个版本。通用解析通常比特定于平台的解析受到更多限制,因为我们需要考虑所有标记的需求。
在通用解析期间,所有必需的包必须与 pyproject.toml 中声明的整个 requires-python 范围兼容。例如,如果项目的 requires-python 是 >=3.8,而给定依赖项的所有版本都要求 Python 3.9 或更高版本,则解析将失败,因为该依赖项缺乏可用于(例如)Python 3.8(即项目支持范围的下限)的可用版本。换句话说,项目的 requires-python 必须是其所有依赖项的 requires-python 的子集。
在为给定依赖项选择兼容版本时,uv 将(默认情况下)尝试为每个支持的 Python 版本选择最新的兼容版本。例如,如果项目的 requires-python 是 >=3.8,并且依赖项的最新版本要求 Python 3.9 或更高版本,而之前所有版本都支持 Python 3.8,则解析器将为运行 Python 3.9 或更高版本的用户选择最新版本,并为运行 Python 3.8 的用户选择先前版本。
在评估依赖项的 requires-python 范围时,uv 仅考虑下限,完全忽略上限。例如,>=3.8, <4 被视为 >=3.8。尊重 requires-python 的上限通常会导致逻辑上正确但在实践中错误的解析结果,因为例如,解析器会回溯到省略上限的第一个发布版本(请参阅:Requires-Python 上限)。
有限的解析环境
默认情况下,通用解析器尝试为所有平台和 Python 版本进行求解。
如果你的项目仅支持有限的一组平台或 Python 版本,你可以通过 environments 设置限制已求解的平台集,该设置接受 PEP 508 环境标记列表。换句话说,你可以使用 environments 设置来“缩减”支持的平台集。
例如,要将锁文件限制为 macOS 和 Linux,并避免为 Windows 进行求解:
或者,要避免为替代 Python 实现进行求解:
environments 设置中的条目必须是不相交的(即它们不能重叠)。例如,sys_platform == 'darwin' 和 sys_platform == 'linux' 是不相交的,但 sys_platform == 'darwin' 和 python_version >= '3.9' 不是,因为两者可能同时为真。
必要环境
在 Python 生态系统中,包可以作为源代码分发版、构建分发版(wheel)或两者同时发布;但要安装包,需要一个构建分发版。如果一个包缺乏构建分发版,或者缺乏当前平台或 Python 版本的构建分发版(构建分发版通常是特定于平台的),uv 将尝试从源代码构建该包,然后安装生成的构建分发版。
某些包(如 PyTorch)发布构建分发版,但省略了源代码分发版。这些包“仅”能在有可用构建分发版的平台上安装。例如,如果一个包发布了 Linux 的构建分发版,但没有 macOS 或 Windows 的,那么该包“仅”能在 Linux 上安装。
缺乏源代码分发版的包会导致通用解析出现问题,因为通常至少有一个平台或 Python 版本无法安装该包。
默认情况下,uv 要求每个此类包至少包含一个与目标 Python 版本兼容的 wheel。required-environments 设置可用于确保生成的解析结果包含针对特定平台的 wheel,或者如果无可用的此类 wheel 则失败。该设置接受 PEP 508 环境标记列表。
虽然 environments 设置“限制”了 uv 在解析依赖项时将考虑的环境集,但 required-environments“扩展”了 uv 在解析依赖项时“必须”支持的平台集。
例如,environments = ["sys_platform == 'darwin'"] 会将 uv 限制为仅为 macOS 进行求解(并忽略 Linux 和 Windows)。另一方面,required-environments = ["sys_platform == 'darwin'"] 将“要求”任何没有源代码分发版的包必须包含一个适用于 macOS 的 wheel 才能安装(如果没有此类 wheel,则会失败)。
在实践中,required-environments 对于声明对非最新平台的显式支持很有用,因为这通常需要回溯并跳过这些包的最新发布版本。例如,要保证任何仅有构建分发版的包都包含对 Intel macOS 的支持:
[tool.uv]
required-environments = [
"sys_platform == 'darwin' and platform_machine == 'x86_64'"
]
常见标记值
environments 和 required-environments 设置接受 PEP 508 环境标记。这些标记的值派生自 Python 运行时(例如 sys.platform, platform.machine(), platform.system() 和 os.name)。
作为快速参考,按平台划分的最常见标记值如下:
| 标记 | Linux | macOS | Windows |
|---|---|---|---|
sys_platform |
'linux' |
'darwin' |
'win32' |
platform_system |
'Linux' |
'Darwin' |
'Windows' |
platform_machine (x86-64) |
'x86_64' |
'x86_64' |
'AMD64' |
platform_machine (ARM64) |
'aarch64' |
'arm64' |
'ARM64' |
os_name |
'posix' |
'posix' |
'nt' |
注意
在 Windows 上,即使在 64 位系统上,sys_platform 也始终为 'win32'。
你可以通过运行以下命令查看当前平台的值:
依赖项首选项
如果存在解析输出文件(即 uv 锁文件 (uv.lock) 或需求输出文件 (requirements.txt)),uv 将“优先”使用其中列出的依赖项版本。同样,如果将包安装到虚拟环境中,如果存在,uv 将优先使用已安装的版本。这意味着除非请求了不兼容的版本,或者通过 --upgrade 显式请求升级,否则锁定的或已安装的版本不会更改。
解析策略
默认情况下,uv 尝试使用每个包的最新版本。例如,uv pip install flask>=2.0.0 将安装 Flask 的最新版本,例如 3.0.0。如果 flask>=2.0.0 是项目的依赖项,则只会使用 flask 3.0.0。这一点很重要,例如,因为运行测试不会检查项目是否真正与它声明的 flask 2.0.0 下限兼容。
使用 --resolution lowest,uv 将为所有直接和间接(传递)依赖项安装尽可能最低的版本。或者,--resolution lowest-direct 将对所有直接依赖项使用最低的兼容版本,而对所有其他依赖项使用最新的兼容版本。uv 将始终为构建依赖项使用最新版本。
例如,给定以下 requirements.in 文件:
运行 uv pip compile requirements.in 将生成以下 requirements.txt 文件:
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in
blinker==1.7.0
# via flask
click==8.1.7
# via flask
flask==3.0.0
itsdangerous==2.1.2
# via flask
jinja2==3.1.2
# via flask
markupsafe==2.1.3
# via
# jinja2
# werkzeug
werkzeug==3.0.1
# via flask
然而,uv pip compile --resolution lowest requirements.in 将改为生成:
# This file was autogenerated by uv via the following command:
# uv pip compile requirements.in --resolution lowest
click==7.1.2
# via flask
flask==2.0.0
itsdangerous==2.0.0
# via flask
jinja2==3.0.0
# via flask
markupsafe==2.0.0
# via jinja2
werkzeug==2.0.0
# via flask
在发布库时,建议在持续集成中单独运行带有 --resolution lowest 或 --resolution lowest-direct 的测试,以确保与声明的下限兼容。
预发布版本处理
默认情况下,uv 在两种情况下会在依赖项解析期间接受预发布版本:
- 如果该包是直接依赖项,并且其版本说明符包含预发布说明符(例如
flask>=2.0.0rc1)。 - 如果包的所有已发布版本都是预发布版本。
如果由于传递性预发布版本导致依赖项解析失败,uv 将提示使用 --prerelease allow 以允许所有依赖项的预发布版本。
或者,可以将传递性依赖项添加为 约束 或直接依赖项(即在 requirements.in 或 pyproject.toml 中),并带有预发布版本说明符(例如 flask>=2.0.0rc1),以选择性地为该特定依赖项启用预发布支持。
预发布版本极其难以建模,并且在其他打包工具中是常见的错误来源。uv 的预发布处理是“有意”受限的,并要求用户选择启用预发布版本以确保正确性。
有关更多详细信息,请参阅 预发布兼容性。
多版本解析
在通用解析期间,由于不同的平台或 Python 版本可能需要不同的版本,因此同一个包可能会在同一个锁文件中多次列出,并带有不同的版本或 URL。
--fork-strategy 设置可用于控制 uv 在 (1) 最小化所选版本数量和 (2) 为每个平台选择尽可能最新的版本之间进行权衡。前者导致跨平台的一致性更高,而后者则导致在可能的情况下使用较新的包版本。
默认情况下(--fork-strategy requires-python),uv 将优化为每个支持的 Python 版本选择每个包的最新版本,同时最小化跨平台的所选版本数量。
例如,当解析具有 >=3.8 Python 要求的 numpy 时,uv 将选择以下版本:
numpy==1.24.4 ; python_version == "3.8"
numpy==2.0.2 ; python_version == "3.9"
numpy==2.2.0 ; python_version >= "3.10"
此解析反映了 NumPy 2.2.0 及更高版本至少需要 Python 3.10 的事实,而早期版本与 Python 3.8 和 3.9 兼容。
在 --fork-strategy fewest 下,uv 将改为最小化每个包的所选版本数量,优先使用与更广泛的支持 Python 版本或平台兼容的旧版本。
例如,在上述场景中,uv 将为所有 Python 版本选择 numpy==1.24.4,而不是针对 Python 3.9 升级到 numpy==2.0.2,针对 Python 3.10 及更高版本升级到 numpy==2.2.0。
依赖约束
与 pip 一样,uv 支持约束文件 (--constraint constraints.txt),它们缩小了给定包的可接受版本集。约束文件类似于需求文件,但仅列为约束不会导致包被包含在解析中。相反,约束仅在请求的包作为直接或传递依赖项被引入时才会生效。约束对于减少传递依赖项的可用版本范围很有用。它们还可以用于使解析与另一组已解析的版本保持同步,而不论这两者之间重叠的包是什么。
依赖覆盖
依赖覆盖允许通过覆盖包声明的依赖项来绕过不成功或不受欢迎的解析结果。在你知道某个依赖项实际上与包的某个特定版本兼容,尽管元数据指出的情况相反时,覆盖是一个有用的最后手段。
例如,如果传递依赖项声明了需求 pydantic>=1.0,<2.0,但实际上可以在 pydantic>=2.0 下工作,用户可以通过在覆盖中包含 pydantic>=1.0,<3 来覆盖声明的依赖项,从而允许解析器选择较新版本的 pydantic。
具体而言,如果 pydantic>=1.0,<3 被包含为覆盖,uv 将忽略所有关于 pydantic 的声明需求,并用覆盖内容替换它们。在上面的示例中,pydantic>=1.0,<2.0 需求将被完全忽略,并被 pydantic>=1.0,<3 取代。
虽然约束只能“减少”包的可接受版本集,但覆盖可以“扩展”可接受版本集,为错误的上限版本提供了一条逃生路径。与约束一样,覆盖不会添加对包的依赖,并且仅在包被直接或传递依赖项请求时才会生效。
在 pyproject.toml 中,使用 tool.uv.override-dependencies 定义覆盖列表。在兼容 pip 的接口中,可以使用 --override 选项传入与约束文件格式相同的文件。
如果为同一个包提供了多个覆盖,则必须用标记加以区分。如果一个包有带标记的依赖项,在使用覆盖时,它是无条件被替换的——标记评估为真或假并不重要。
依赖元数据
在解析期间,uv 需要解析遇到的每个包的元数据,以确定其依赖项。此元数据通常在包索引中作为静态文件提供;但是,对于仅提供源代码分发的包,元数据可能无法提前获取。
在这种情况下,uv 必须构建该包以确定其元数据(例如,通过调用 setup.py)。这可能会在解析期间引入性能损失。此外,它强加了该包必须能在所有平台上构建的要求,这可能并非总是如此。
例如,你可能有一个包应该仅在 Linux 上构建和安装,但在 macOS 或 Windows 上无法成功构建。虽然 uv 可以为这种情况构建一个完全有效的锁文件,但这样做需要构建该包,而这在非 Linux 平台上会失败。
tool.uv.dependency-metadata 表可用于提前提供此类依赖项的静态元数据,从而允许 uv 跳过构建步骤并使用提供的元数据。
例如,要提前为 chumpy 提供元数据,请在 pyproject.toml 中包含其 dependency-metadata:
[[tool.uv.dependency-metadata]]
name = "chumpy"
version = "0.70"
requires-dist = ["numpy>=1.8.1", "scipy>=0.13.0", "six>=1.11.0"]
这些声明旨在用于包“不”提前声明静态元数据的情况,尽管它们对于需要禁用构建隔离的包也很有用。在这些情况下,提前声明包元数据可能比在解析包之前创建自定义构建环境更容易。
例如,过去版本的 flash-attn 没有声明静态元数据。通过提前为 flash-attn 声明元数据,uv 可以解析 flash-attn 而无需从源代码构建包(这本身需要安装 torch)。
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["flash-attn"]
[tool.uv.sources]
flash-attn = { git = "https://github.com/Dao-AILab/flash-attention", tag = "v2.6.3" }
[[tool.uv.dependency-metadata]]
name = "flash-attn"
version = "2.6.3"
requires-dist = ["torch", "einops"]
与依赖覆盖一样,tool.uv.dependency-metadata 也可以用于包的元数据不正确或不完整,或者包在包索引中不可用的情况。虽然依赖覆盖允许全局覆盖包的允许版本,但元数据覆盖允许覆盖“特定包”的声明元数据。
注意
tool.uv.dependency-metadata 中的 version 字段对于基于注册表的依赖项是可选的(如果省略,uv 将假设元数据适用于该包的所有版本),但对于直接 URL 依赖项(如 Git 依赖项)是“必需的”。
tool.uv.dependency-metadata 表中的条目遵循 Metadata 2.3 规范,不过 uv 仅读取 name、version、requires-dist、requires-python 和 provides-extra。version 字段也被视为可选。如果省略,元数据将用于指定包的所有版本。
冲突的依赖项
uv 要求项目声明的所有依赖项相互兼容,并在创建锁文件时一起解析所有依赖项。这包括项目依赖项、可选依赖项(“extras”)和依赖组(开发依赖项)。
如果在一个 extra 中声明的依赖项与另一个 extra 中的依赖项不兼容,uv 将解析项目需求失败并报错。例如,考虑两组相互冲突的可选依赖项:
如果你运行带有上述依赖项的 uv lock,解析将失败:
$ uv lock
x No solution found when resolving dependencies:
`-> Because myproject[extra2] depends on numpy==2.0.0 and myproject[extra1] depends on numpy==2.1.2, we can conclude that myproject[extra1] and
myproject[extra2] are incompatible.
And because your project requires myproject[extra1] and myproject[extra2], we can conclude that your projects's requirements are unsatisfiable.
为了绕过这个问题,uv 支持显式声明冲突。如果你指定 extra1 和 extra2 是冲突的,uv 将分别解析它们。在 tool.uv 部分指定冲突:
现在,运行 uv lock 将成功。但是,现在你不能同时安装 extra1 和 extra2:
$ uv sync --extra extra1 --extra extra2
Resolved 3 packages in 14ms
error: extra `extra1`, extra `extra2` are incompatible with the declared conflicts: {`myproject[extra1]`, `myproject[extra2]`}
发生此错误是因为同时安装 extra1 和 extra2 将导致在同一个环境中安装同一个包的两个不同版本。
上述处理冲突可选依赖项的策略也适用于依赖组:
[dependency-groups]
group1 = ["numpy==2.1.2"]
group2 = ["numpy==2.0.0"]
[tool.uv]
conflicts = [
[
{ group = "group1" },
{ group = "group2" },
],
]
与冲突 extras 的唯一区别在于你需要使用 group 键而不是 extra。
在使用包含多个项目的工作区时,同样的限制也适用——uv 要求所有工作区成员相互兼容。同样,可以在工作区成员之间声明冲突。
例如,考虑以下工作区:
[project]
name = "member1"
[project.optional-dependencies]
extra1 = ["numpy==2.1.2"]
[project]
name = "member2"
[project.optional-dependencies]
extra2 = ["numpy==2.0.0"]
要声明这些不同工作区成员中 extras 之间的冲突,请使用 package 键:
[tool.uv]
conflicts = [
[
{ package = "member1", extra = "extra1" },
{ package = "member2", extra = "extra2" },
],
]
一个工作区成员的项目依赖项(即 project.dependencies)也可能与另一个成员的 extra 冲突,例如:
[project]
name = "member2"
[project.optional-dependencies]
extra2 = ["numpy==2.0.0"]
此冲突也可以使用 package 键声明:
[tool.uv]
conflicts = [
[
{ package = "member1" },
{ package = "member2", extra = "extra2" },
],
]
同样,某些工作区成员可能具有冲突的项目依赖项:
此冲突也可以使用 package 键声明:
这些工作区成员将无法同时安装,例如,工作区根目录不能定义:
下限
默认情况下,uv add 会为依赖项添加下限。当使用 uv 管理项目时,如果直接依赖项没有下限,uv 会发出警告。
下限在“快乐路径”中并不是关键的,但在存在依赖项冲突的情况下很重要。例如,考虑一个需要两个包的项目,而这两个包有冲突的依赖项。解析器需要检查这两个包在约束内的所有版本组合——如果它们都冲突,则会报告错误,因为依赖项不可满足。如果没有下限,解析器可以(且通常会)回溯到包的最旧版本。这不仅因为速度慢而有问题,旧版本的包通常无法构建,或者解析器最终可能会选择一个足够旧的版本,它不依赖于冲突的包,但也不适用于你的代码。
在编写库时,下限尤为关键。声明你的库所适用的每个依赖项的最低版本,并验证界限是否正确(使用 --resolution lowest 或 --resolution lowest-direct 进行测试)非常重要。否则,用户可能会收到你的库的依赖项中过旧、不兼容的版本,从而导致库出现意外错误而失败。
可复现的解析
uv 支持 --exclude-newer 选项,将解析限制为在特定日期之前发布的发行版,从而允许复现安装,不受新包发布的影响。日期可以指定为 RFC 3339 时间戳(例如 2006-12-02T02:07:43Z)或系统中配置的时区内相同格式的本地日期(例如 2006-12-02)。
重要
包索引必须支持 PEP 700 中指定的 upload-time 字段。如果给定发行版不存在该字段,除非通过 --exclude-newer-package <package>=false 排除该包,否则该发行版将被视为不可用。PyPI 为所有包提供 upload-time。
为了确保可复现性,不可满足的解析消息将不会提及由于 --exclude-newer 标志而排除了发行版——较新的发行版将被视为不存在。
注意
--exclude-newer 选项仅应用于从注册表读取的包(而不是 Git 依赖项等)。此外,在使用 uv pip 接口时,除非提供了 --reinstall 标志(在这种情况下 uv 将执行新的解析),否则 uv 不会降级之前已安装的包。
此选项在 pyproject.toml 中也受支持,例如:
在持久配置中指定时,不允许使用本地日期时间。
也可以为特定包指定值,例如 --exclude-newer-package setuptools=2006-12-02,或者:
相同的标志也接受 <package>=false 以允许包退出 --exclude-newer 限制,例如,允许从不发布上传时间的索引中解析包。
特定包的值将优先于全局值。
依赖冷却
uv 还支持依赖项“冷却”,其中解析将忽略比某个持续时间更新的包。这是提高安全态势的好方法,通过推迟包更新,直到社区有机会审查包的新版本。
此功能通过 exclude-newer 选项提供,并共享相同的语义。
通过指定持续时间而不是绝对值来定义依赖项冷却。可以使用“友好”的持续时间(例如 24 hours, 1 week, 30 days)或 ISO 8601 持续时间(例如 PT24H, P7D, P30D)。
注意
持续时间不遵守本地时区的语义,并始终被解析为固定的秒数(假设一天为 24 小时,例如忽略夏令时转换)。不允许使用月份和年份等日历单位,因为它们本质上是不一致的长度。
当持续时间用于解析时,时间戳是相对于当前时间计算的。使用 uv.lock 文件时,时间戳包含在锁文件中。当当前时间发生变化时,uv 不会更新锁文件;相反,uv 会在执行新的解析时(例如使用 --upgrade 或 --refresh 时)更新时间戳。
此选项在 pyproject.toml 中也受支持,例如:
也可以为特定包指定值,例如 --exclude-newer-package "setuptools=30 days",或者:
源代码分发
PEP 625 规定包必须将源代码分发版分发为 gzip 压缩包 (.tar.gz) 归档文件。在此规范之前,为了向后兼容,也允许使用其他需要支持的归档格式。uv 支持读取和解压以下格式的归档文件:
- gzip 压缩包 (
.tar.gz,.tgz) - bzip2 压缩包 (
.tar.bz2,.tbz) - xz 压缩包 (
.tar.xz,.txz) - zstd 压缩包 (
.tar.zst) - lzip 压缩包 (
.tar.lz) - lzma 压缩包 (
.tar.lzma) - zip (
.zip)
锁文件版本控制
uv.lock 文件使用版本化架构。架构版本包含在锁文件的 version 字段中。
任何给定版本的 uv 都可以读取和写入具有相同架构版本的锁文件,但会拒绝具有更高架构版本的锁文件。例如,如果你的 uv 版本支持架构 v1,那么如果遇到现有的 v2 架构锁文件,uv lock 将报错。
支持 v2 架构的 uv 版本“可能”能够读取 v1 架构的锁文件(如果架构更新是向后兼容的)。然而,这不能保证,如果 uv 遇到具有过时架构版本的锁文件,可能会退出并报错。
架构版本被视为公共 API 的一部分,因此仅在次要版本中作为重大更改进行提升(请参阅 版本控制)。因此,给定次要 uv 版本内的所有 uv 修补程序版本都保证具有完整的锁文件兼容性。换句话说,锁文件可能仅跨越次要版本被拒绝。
锁文件的 revision 字段用于跟踪对锁文件的向后兼容更改。例如,向发行版添加新字段。修订版本的更改不会导致旧版本的 uv 报错。
了解更多
有关解析器内部的更多详细信息,请参阅解析器参考文档。