Python 版本号比较 !=(不等于)
Python version number comparison with != (not equal)
我正在尝试编写一个函数来复制 python_requires
from setup.py
, because I failed to find the implementation in the source code of setuptools and pip. Comparing version numbers in Python should be easy enough, I'm using packaging.version 的行为,它为我完成所有工作,除了...
让我们看一下像 ">=2.6, !=3.0.*, !=3.1.*"
这样的版本字符串。我在每个逗号处分开,然后分别查看每个比较:
from packaging import version
version.parse("3.0.5") >= version.parse("2.6")
版本 3.0.5 大于 2.6,符合预期。下一篇:
version.parse("3.0.5") != version.parse("3.0.*")
这个 returns 正确(即 3.0.5
与 3.0.*
不同 ,但版本 3.0.5
实际上应该匹配 3.0.*
。 Python 中是否有标准方法来检查带通配符的版本号是否与另一个版本号匹配?
edit:也相关,我将如何实现兼容的版本匹配器,如 ~= 3.0.5
,它应该匹配任何版本 >= 3.0.5
但 < 3.1.0
?
看来我正在尝试在此处实现 PEP 440 的版本说明符...
根据the documentation packaging.version.parse
is only intended to parse PEP 440兼容版本号,其中"3.0.*"
不是一个。通配符的使用在 PEP 中被称为在匹配时有效,但它们实际上并不是版本方案的一部分。
当 packaging.version.parse
被赋予一个不兼容的版本号进行解析时,它将作为 packaging.version.LegacyVersion
而不是 packaging.version.Version
返回。您可以确认这是在您的案例中返回的内容。据推测,操作员在这些方面的工作方式不同(可能根本没有实现),并且他们在设置工具中实现了一些额外的逻辑来处理 LegacyVersion
个对象。
如果您的最终目标只是将版本兼容性与 PEP 440 版本说明符进行比较,看起来 packaging.specifiers
已经支持这个:
>>> from packaging.specifiers import SpecifierSet
>>> vspec = SpecifierSet(">=11.3,!=11.3.2")
>>> "11.3.1" in vspec
True
>>> "11.3.2" in vspec
False
>>>
如果您真的打算自己实施,specifiers.py source 可能会有所帮助。看起来一般的方法是对每个运算符进行正则表达式匹配,将它们映射到适当的 Specifier
方法,在任何特殊处理后比较被推迟到 Version
运算符(例如,_compare_equal()
处理".*" 你问的情况)。
我正在尝试编写一个函数来复制 python_requires
from setup.py
, because I failed to find the implementation in the source code of setuptools and pip. Comparing version numbers in Python should be easy enough, I'm using packaging.version 的行为,它为我完成所有工作,除了...
让我们看一下像 ">=2.6, !=3.0.*, !=3.1.*"
这样的版本字符串。我在每个逗号处分开,然后分别查看每个比较:
from packaging import version
version.parse("3.0.5") >= version.parse("2.6")
版本 3.0.5 大于 2.6,符合预期。下一篇:
version.parse("3.0.5") != version.parse("3.0.*")
这个 returns 正确(即 3.0.5
与 3.0.*
不同 ,但版本 3.0.5
实际上应该匹配 3.0.*
。 Python 中是否有标准方法来检查带通配符的版本号是否与另一个版本号匹配?
edit:也相关,我将如何实现兼容的版本匹配器,如 ~= 3.0.5
,它应该匹配任何版本 >= 3.0.5
但 < 3.1.0
?
看来我正在尝试在此处实现 PEP 440 的版本说明符...
根据the documentation packaging.version.parse
is only intended to parse PEP 440兼容版本号,其中"3.0.*"
不是一个。通配符的使用在 PEP 中被称为在匹配时有效,但它们实际上并不是版本方案的一部分。
当 packaging.version.parse
被赋予一个不兼容的版本号进行解析时,它将作为 packaging.version.LegacyVersion
而不是 packaging.version.Version
返回。您可以确认这是在您的案例中返回的内容。据推测,操作员在这些方面的工作方式不同(可能根本没有实现),并且他们在设置工具中实现了一些额外的逻辑来处理 LegacyVersion
个对象。
如果您的最终目标只是将版本兼容性与 PEP 440 版本说明符进行比较,看起来 packaging.specifiers
已经支持这个:
>>> from packaging.specifiers import SpecifierSet
>>> vspec = SpecifierSet(">=11.3,!=11.3.2")
>>> "11.3.1" in vspec
True
>>> "11.3.2" in vspec
False
>>>
如果您真的打算自己实施,specifiers.py source 可能会有所帮助。看起来一般的方法是对每个运算符进行正则表达式匹配,将它们映射到适当的 Specifier
方法,在任何特殊处理后比较被推迟到 Version
运算符(例如,_compare_equal()
处理".*" 你问的情况)。