此 PEP 指定了一种文件格式,用于列出项目的 Python 包安装要求。项目列表对于安装目标被认为是详尽无遗的,因此被锁定,除了正在安装的平台和列出所需依赖项的锁定文件之外,不需要任何信息来执行依赖项的成功安装。感谢 PEP 621,项目可以列出他们需要安装的直接/顶级依赖项。但是 PEP 621 也(有目的地)省略了两个通常对项目很重要的关键细节:由于各种原因,这两种需求都很重要。一个是,如果没有完整列出所有依赖项和要使用的特定版本,同一项目的开发人员或开发人员和用户之间可能会出现偏差,这取决于安装时项目的依赖项的哪些版本可用。例如,当一个开发人员安装该依赖项时,某个依赖项可能在星期一将 v1 作为最新版本,而当另一个开发人员安装相同的依赖项时,v2 在星期三发布。现在这两个开发人员正在针对相同依赖项的两个不同版本工作,这可能会导致不同的结果。可重复安装的另一个重要原因是出于安全目的。确保为所有安装下载并安装相同的二进制数据可确保没有恶意者以某种方式恶意更改依赖项的二进制数据。锁定文件可以通过记录应该安装什么的确切细节以及如何验证这些依赖项没有意外更改任何字节来帮助实现这一保证。基于多个工具独立创建了自己的锁文件格式这一事实,社区本身也表现出对锁文件的需求:其他编程语言社区也通过开发自己的解决方案来展示锁文件的实用性。其中一些社区包括: 首先,应定义两个关键术语。 Locker 是一种生成锁文件的工具。安装程序是一种使用锁定文件来安装适当依赖项的工具。
文件格式应该是机器可读、机器可写和人类可读的。由于假设绝大多数lockfile 将由locker 工具生成,因此该格式应该易于由locker 编写。由于安装工具将使用锁定文件,因此安装程序还需要轻松读取该格式。但该格式也应该是人可读的,因为人们将不可避免地对锁定文件进行审核。拥有不适合被人们阅读的格式会阻碍这一点。这包括对以 diff 格式可读的锁定文件的更改,以便审核更改。这也意味着理解为什么某些东西在锁文件中应该可以在 diff 中理解,以帮助审计更改。锁文件格式需要足够通用,以支持跨平台和跨环境的依赖项规范。这允许拥有一个可以在无数平台和环境上工作的单个锁文件,如果有意义的话。这已被 Python 包装生态系统中的各种工具显示为必要的功能,这些工具已经具有锁定文件格式(例如 Pipenv [10]、Poetry [12]、PDM [8])。锁定文件还需要支持可重现的安装。如果有人想将锁定文件覆盖的内容限制在单个平台上以保证将安装的确切依赖项和文件,那应该是可行的。这在 SecureDrop [16] 等项目的安全上下文中可能是至关重要的。当可以在储物柜或安装器中执行计算时,优选在储物柜中执行计算。这是因为假设储物柜的执行频率低于安装程序。安装程序应该能够完全根据平台/环境信息以及锁定文件中包含的内容来解决要安装的内容。应该不需要使用网络或其他文件系统 I/O 来解决要安装的内容。锁定文件应提供足够的灵活性以允许储物柜和安装人员进行创新。虽然锁定文件规范提供了功能的公分母,但它不应作为功能的上限。由于锁定文件的预期大小,没有努力使锁定文件可人工写入。
由于 PEP 518 为 pyproject.toml 采用了 TOML [19] 文件格式,锁定文件必须使用 TOML [19] 文件格式。这不仅可以防止 Python 打包生态系统中需要另一种文件格式,而且还有助于使锁定文件易于人类阅读。锁定文件必须保存在名为 pyproject-lock.d.Lock 文件的目录中,必须以 .toml 文件扩展名结尾。项目可以使用他们选择的任何文件名词干拥有任意数量的锁定文件。此 PEP 没有规定在多个锁定文件之间自动选择的特定方法,安装程序应避免猜测哪个锁定文件是“最合适的”(这并不排除预期仅存在具有特定名称的单个锁定文件并将默认使用的情况,例如,文档托管站点在提供时始终使用名为 pyproject-lock.d/rftd.toml 的锁定文件)。正在使用的锁定文件的版本。必须指定密钥,并且必须将其设置为 1。该数字必须始终是一个整数,并且它必须仅在规范的未来更新中递增。构成版本号增加的内容留给未来的 PEP 或标准更改。工具可以在工具表下创建自己的子表。此表的规则与构建系统声明规范 [1] 中 pyproject.toml 及其 [工具] 表的规则相匹配。表的每个键都是一个包的名称,必须根据简单的存储库 API [17] 进行规范化。如果将附加项指定为要安装的项目的一部分,则附加项将包含在键名中并按字典顺序排序。 version = 1[tool]# Tool-specific table ala PEP 518's `[tool]` table.[metadata]marker = "python_version>='3.6'"needs = ["mousebender"][[package.attrs]]version = "21.2.0"required-by = ["mousebender"][[package.attrs.code]]type = "wheel"url = "https://files.pythonhosted.org/packages/20/a9/ba6f1cd1a1517ff022b35acd6a7e4246371dfab08b7d9e4dfab08b7d9e4c -21.2.0-py2.py3-none-any.whl"hash-algorithm="sha256"hash-value = "149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da0088356da0.b.7"20000000000000000000" 19.3", "packaging>=20.3"][[package.mousebender.code]]type = "sdist"url = "https://files.pythonhosted.org/packages/35/bc/db77f8ca1ccf85f5c3324e4f62fc74bf6f6c0780d04bf6f6c0790d04bf6f6c07d80304b .tar.gz"hash-algorithm = "sha256"hash-value = "c5953026378e5dcc7090596dfcbf73aa5a9786842357273b1df974ebd79bd760"[[package.mousebd760"[package.mousebender/code.mousebender/org.mousebender. b3/f6fdbff6395e9b77b5619160180489410fb2f42f41272994353e7ec f5bdf/mousebender-2.0.0-py3-none-any.whl"hash-algorithm = "sha256"hash-value = "a6f9adfbd17bfb0e6bb5de9a27083e01dfb86ed9c3861e04143d.904143d7"2fdpar. .2"]required-by = ["mousebender"][[package.packaging.code]]type = "git"url = "https://github.com/pypa/packaging.git"commit = "53fd698b1620aca027324001bf53c8ffda0c17d1"[ [package.pyparsing]]version = "2.4.7"required-by = ["packaging"][[package.pyparsing.code]]type="wheel"url = "https://files.pythonhosted.org/packages /8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl"hash-algorithm="sha256"hash-value="ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"interpreter-tag = “py2.py3” ABI-标签= "none"platform-tag = "any" 安装程序必须实现已安装发行版规范 [14] 的直接 URL 来源,因为从锁定文件安装的所有软件包本质上都源自 URL,而不是通过软件包名称和 ve 搜索索引信。
让用户指定他们想要在 pyproject-lock.d(例如 dev、prod)中使用哪个锁定文件 从 metadata.needs 和 foreach 列出的包中收集包名称列表......对中列出的包重复上述步骤找到要安装的每个软件包的需求密钥 因为没有关于锁定文件的预先存在的规范,所以没有明确的向后兼容性问题。对于具有自己的锁定文件的预先存在的工具,将需要进行一些更新。大多数记录锁定文件名,但不记录其内容,在这种情况下,锁定文件的文件名是重要的部分。对于不提交其锁定文件版本控制的项目,他们将需要更新其 .gitignore 文件的等效文件。对于提交锁定文件版本控制的项目,提交的文件需要更新。对于像 pipenv [10] 那样记录锁定文件格式的项目,他们很可能需要一个新的主要版本发布。特别是对于 Poetry [12],它有一个导出命令,即使项目选择不采用这种 PEP 作为 Poetry 的主要锁定文件格式,它也应该允许 Poetry 支持这种锁定文件格式。锁定文件不应引入安全问题,而是有助于解决这些问题。通过要求记录代码的散列,锁定文件能够帮助防止篡改代码,因为记录了散列详细信息。锁定文件还有助于防止安装可能是恶意的意外包更新。
本 PEP 的教学在很大程度上取决于日常使用的储物柜和安装人员。但是,从概念上讲,可以教导用户 pyproject-lock.d 目录包含指定应该安装什么才能使项目工作的文件。应该强调一致性和安全性的好处,以帮助用户意识到他们为什么应该关心锁定文件。决定与 TOML 合作。有人担心 Python 的标准库缺少 TOML 解析器,但由于 pyproject.toml,大多数打包工具已经使用了 TOML 解析器,因此这个问题似乎并没有引起轰动。过去,有些人还反对这种担忧,因为如果打包工具讨厌安装依赖项并且觉得他们不能提供包,那么打包生态系统需要纠正的问题比需要依赖第三方 TOML 解析器要大得多。曾经考虑过不使用锁定文件目录而是使用包含所有可能锁定信息的单个锁定文件的想法。但是很快就很明显,试图设计一种既可以包含可以支持多种环境的锁定文件格式又可以包含用于可重现构建的严格锁定结果的数据格式将变得非常复杂和麻烦。还考虑了支持锁文件目录以及名为 pyproject-lock.toml 的单锁文件的想法。但是在单个锁定文件的情况下跳过目录的任何可能的简单性似乎是不必要的。尝试为应该是 pyproject-lock.toml 文件的内容以及应该进入 pyproject-lock.d 的内容定义适当的逻辑似乎不必要地复杂。该 PEP 的第一个版本提出锁文件没有依赖图的概念。取而代之的是,锁定文件将准确列出应该为特定平台安装的内容,这样安装人员不必就安装什么做出任何决定,只需验证锁定文件是否适用于目标平台。由于潜在 PEP 508 环境标记的组合数量众多,这个想法最终被否决。当一个项目想要跨平台时,决定尝试让储物柜生成所有可能的组合是太多了。从技术上讲,项目可以在其各种轮文件之间指定不同的依赖关系。考虑到这一点,则需要锁定文件操作不是每个项目而是每个文件。幸运的是,以这种方式指定不同的依赖项非常少见且不受欢迎,因此被认为不值得支持。
而不是单调递增的整数,使用浮点数被认为是试图传达语义版本控制。但是,最终,它被认为比它的价值更麻烦,因为添加新密钥可能会构成“主要”版本更改(只有当密钥完全可选时才会被视为“次要”),并且具有核心元数据规范的经验[2] 建议有更大的机会,解析将放宽并变得更严格,这也是一个“重大”变化。因此,使用整数的简单性是有意义的。已建议在代码表中允许自定义类型值。它们将以 x- 为前缀,然后是工具名称和类型,即 x-<工具>-<类型>。这将为其他版本控制系统、创新容器格式等提供足够的灵活性,以便在锁定文件中正式使用。这可能包括包含 pyproject-lock.d 的目录的预定义变量,如 PROJECT_ROOT,因此本地目录和文件的 URL 可以相对于项目本身。感谢 PDM [8] 的 Frost Ming 和 Poetry [12] 的 Sébastien Eustace 提供有关 PEP 508 要求的动态安装时间解决方案的输入。本文档被置于公共领域或 CC0-1.0-Universal 许可下,以更宽松的为准。来源:https://github.com/python/peps/blob/master/pep-0665.rst