"package===version" 形式的 setuptools 要求的目的是什么

What is the purpose of setuptools requirements of the form "package===version"

假设我有一个带有控制台脚本的包,例如

from setuptools import setup
setup(
    name='eg_package',
    version='0.0.1',
    description='Trivial test package',
    packages=[
       'eg_package',
    ],
    entry_points={
        'console_scripts': [
            'foo = eg_package.main:main',
        ]
   },
)

如果我使用 egg_info -b mytag 设置和显式构建标记,生成的脚本具有 __requires__ = 'eg-package===0.0.1mytag',即带有 3 个“=”符号。当标记不是像 b1 测试版那样的常规标记时,就会发生这种情况。

起初我认为这是一个错误,但 setuptools 文档表明它是一个有效的需求标识符。但是,它不适用于旧版本的设置工具,这会导致我们的系统出现问题。

我的问题是 "===" 是什么意思,为什么现代 setuptools 使用它?

Requirement specifier section in pip docs links to the official docs for requirement specifiers implemented by setuptools pkg_resources。它指定了形式语法,但没有说明语义。 Overview docs 解释语义,但对 ~==== 的内容只字未提,这些内容显然是在 vv.7(与 python 2.7.9 一起安装)和 16 之间添加的。

当文档失败时,是时候查阅资源了。下载 setuptools hg repo and annotating pkg_resources/__init__.py ultimately brings us to changeset 3125 消息 "Implement PEP 440 by using the packaging library".

的确,PEP 440, Version Specifiers section 解释了语法和语义:

通过检查提交中的其他文件和相关的 packaging 包,我得出了这些显而易见的结论:

  • ~= 永远不会产生;当处理 1 时,它根据 PEP 中概述的规则充当过滤器。
  • ===,在处理时,发出回退到旧 setuptools 版本语法和比较逻辑的信号。只要生成的版本字符串不符合 PEP2.
  • ,就会生成它

1pkg_resources._vendor.packaging.specifiers._compare_compatible() 2pkg_resources.parse_version() 生成 pkg_resources.SetuptoolsLegacyVersion 而不是 pkg_resources.SetuptoolsVersion