如何在Python中处理插件的版本控制?
我有一个基于插件的库,在这些早期阶段,库经常发生变化。我希望插件保持现有状态,即使它们在更新后松散与库的兼容性,以便允许用户对特定插件的警告不再是最新的
requirements.txt
语法每个插件都是它自己的类,并定义了一个requires
字符串,例如 pyblish< = 1 。然后有一个库的当前版本。以下is_compatible
允许将requirements.txt
样式字符串与任意version_info
样式版本进行比较。
"""Library versioning using the default Python syntax
Example:
>>> is_compatible("pyblish<=1", (0, 9, 0))
True
>>> is_compatible("pyblish>=1.1, <2.1", (2, 0, 0))
True
"""
import re
import operator
def is_compatible(requirement, version):
"""Return whether or not `requirement` is compatible with `version`
Example:
>>> is_compatible("pyblish<=1", (0, 9, 0))
True
>>> is_compatible("pyblish>=1, <1.3", (1, 2, 0))
True
>>> is_compatible("pyblish>=0.9.9", (1, 0, 0))
True
>>> is_compatible("pyblish>=1.1, <2.1", (2, 0, 0))
True
>>> is_compatible("pyblish==1.0.0", (1, 0, 0))
True
>>> is_compatible("pyblish==1.0.0", (1, 0, 1))
False
"""
results = list()
for operator_string, requirement_string in parse_requirements(requirement):
operator = operators[operator_string]
required = string_to_tuple(requirement_string)
result = operator(version, required)
results.append(result)
return all(results)
def parse_requirements(line):
"""From pkg_utils.parse_requirements
Example:
>>> parse_requirements("pyblish==1.0.0")
[('==', '1.0.0')]
>>> parse_requirements("pyblish>=1.1.0")
[('>=', '1.1.0')]
>>> parse_requirements("pyblish>=1.1.0, <1.2")
[('>=', '1.1.0'), ('<', '1.2')]
"""
LINE_END = re.compile(r"\s*(#.*)?$")
DISTRO = re.compile(r"\s*((\w|[-.])+)")
VERSION = re.compile(r"\s*(<=?|>=?|==|!=)\s*((\w|[-.])+)")
COMMA = re.compile(r"\s*,")
match = DISTRO.match(line)
p = match.end()
specs = list()
while not LINE_END.match(line, p):
match = VERSION.match(line, p)
if not match:
raise ValueError(
"Expected version spec in",
line, "at", line[p:])
specs.append(match.group(*(1, 2)))
p = match.end()
match = COMMA.match(line, p)
if match:
p = match.end() # Skip comma
elif not LINE_END.match(line, p):
raise ValueError(
"Expected ',' or end-of-list in",
line, "at", line[p:])
return specs
def string_to_tuple(version):
"""Convert version as string to tuple
Example:
>>> string_to_tuple("1.0.0")
(1, 0, 0)
>>> string_to_tuple("2.5")
(2, 5)
"""
return tuple(map(int, version.split(".")))
operators = {"<": operator.lt,
"<=": operator.le,
"==": operator.eq,
"!=": operator.ne,
">=": operator.ge,
">": operator.gt}
if __name__ == '__main__':
import doctest
doctest.testmod()
你好吗?是否存在处理此类版本控制的现有推荐方法?还有哪些其他语法?
参考文献:requirements.txt,rez,conda,requirements-parser
由于
答案 0 :(得分:0)
在更好的事情出现之前,我已经在GitHub上传了上述示例的精炼版本,以及通过pit / PyPI进行的文档和安装,在MIT下获得许可,可在此处获取:
$ pip install iscompatible
$ python
>>> from iscompatible import iscompatible
>>> iscompatible("foo>=5", (5, 6, 1))
True
>>> iscompatible("foo>=5.6.1, <5.7", (5, 0, 0))
False
>>> MyPlugin = type("MyPlugin", (), {'version': (5, 6, 1)})
>>> iscompatible("foo==5.6.1", MyPlugin.version)
True
我仍然对现有的解决方案或技巧和窍门感兴趣!也许这个包可以帮助更好地定义我的要求。