有没有一种方法可以通过编程确认python包版本满足需求说明符?

2024-06-16 11:19:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到是否有一种方法来获取已安装的包和版本,并检查它是否满足需求规范

例如,如果我有包pip==20.0.2,我希望程序执行以下操作:

CheckReqSpec("pip==20.0.2", "pip>=19.0.0")  -> True
CheckReqSpec("pip==20.0.2", "pip<=20.1")    -> True
CheckReqSpec("pip==20.0.2", "pip~=20.0.0")  -> True
CheckReqSpec("pip==20.0.2", "pip>20.0.2")   -> False

我发现pkg_resources.extern.packaging有version.parse,这对于比较大于或小于的不同版本很有用,但是需求规范可能非常复杂,并且有一些像~=这样的运算符不是标准的数学运算符

setuptools文档有以下示例:

PickyThing<1.6,>1.9,!=1.9.6,<2.0a0,==2.4c1

有没有一个现成的方法来做这个检查,或者一个简单的方法来做我自己的

编辑: 特别是当规范作为变量输入时,~=是很困难的。*在版本需求方面也很难搞清楚,因为

 version.parse("20.0.*") == version.parse("20.0.1") # False
 version.parse("20.0.*") < version.parse("20.0.0")  # True 
 version.parse("20.0.*") < version.parse("20.1.1")  # True 
 version.parse("20.0.*") >= version.parse("20.0.0") # False

Tags: pip方法版本规范falsetrueparseversion
3条回答

使用setuptools解析说明符集,然后使用in检查成员资格:

>>> from pkg_resources import Requirement
>>> req = Requirement.parse("pip~=20.0.0")
>>> pin = "pip==20.0.2"
>>> name, version = pin.split("==")
>>> name == req.name and version in req.specifier
True

发布后工作。必须明确选择预发布版本

>>> "20.0.0post1" in req.specifier
True
>>> req.specifier.contains("20.0.1b3")
False
>>> req.specifier.contains("20.0.1b3", prereleases=True)
True

我建议^{},它可以像以下那样使用:

>>> import packaging.requirements
>>> import packaging.version
>>> packaging.version.parse('20.0.2') in packaging.requirements.Requirement('pip>=19.0.0').specifier
True
>>> packaging.version.parse('20.0.2') in packaging.requirements.Requirement('pip~=20.0').specifier
True
>>> packaging.requirements.Requirement('pip==20.0.*').specifier.contains('20.0.2')
True
>>> packaging.requirements.Requirement('pip==20.0.*').specifier.contains('21')
False
>>> packaging.requirements.Requirement('PickyThing<1.6,>1.9,!=1.9.6,<2.0a0,==2.4c1').specifier
<SpecifierSet('!=1.9.6,<1.6,<2.0a0,==2.4c1,>1.9')>

也许^{}

from packaging import version

version.parse("20.0.2") > version.parse("19.0.0")   # True
version.parse("20.0.2") <= version.parse("20.1")    # True
version.parse("20.0.2") >= version.parse("20.0.0")  # True
version.parse("20.0.2") > version.parse("20.0.2")   # False

相关问题 更多 >