如何在Python中生成与PEP 440版本说明符匹配的示例版本?

rdlzhqv9  于 2023-03-28  发布在  Python
关注(0)|答案(1)|浏览(146)

我有一个PEP 440版本说明符,如">=1.0,<2.0",它定义了Python包的有效版本范围。我想生成一个与此说明符匹配的示例版本列表。
例如,如果说明符是">=1.0,<2.0",则一些有效的示例版本可能是1.0.11.5.31.9.9。无效的示例版本可能是0.9.52.0.03.0.0
在Python(3.10)中生成这样的示例版本最简单的方法是什么?我应该使用正则表达式、打包库还是其他方法?
我目前的方法是在逗号处添加split,并从版本说明符中删除比较运算符,然后使用try创建Version
在下面的示例中,我允许使用无效版本,因为我不介意它们用于我的用例。

from packaging.version import Version, InvalidVersion

comp_ops = ["===", "~=", "<=", ">=", "!=", "==", "<", ">"]    # order matters
version_spec = ">=1.0,<2.0"
versions = []

for v in version_spec.split(','):
    version = v
    for op in comp_ops:
        version = version.removeprefix(op)
    try:
        versions.append(Version(version))
    except InvalidVersion:
        pass
p8h8hvxi

p8h8hvxi1#

我尝试的另一种方法是重复生成r"[0-9]\.[0-9]\.[0-9]"形式的随机字符串,并从中解析版本,直到得到n_samples的许多有效版本。

import random
from packaging.version import parse, Version
from packaging.specifiers import SpecifierSet

def version_samples(specifier: SpecifierSet, n_versions:int=3) -> list[Version]:
    sample_versions = []
    while len(sample_versions) < n_versions:
        version = ".".join(str(random.randint(0, 9)) for _ in range(3))
        parsed_version = parse(version)
        if specifier.contains(parsed_version):
                sample_versions.append(version)
    return sample_versions

specifier = SpecifierSet(">=1.0,<2.0")
print(version_samples(specifier))        # sample output: ['1.9.9', '1.0.4', '1.8.3']

我想这种方法可以扩展到更通用的PEP 440公共版本标识符([N!]N(.N)*[{a|b|rc}N][.postN][.devN])。这种方法的缺点是它是猜测和检查,并且没有(故意)考虑边缘情况。

相关问题