692e200ffe
save startup blend for animation tab & whatnot
86 lines
1.8 KiB
Python
86 lines
1.8 KiB
Python
"""Tolerant version comparator for real-world pipelines."""
|
|
|
|
import re
|
|
from functools import total_ordering
|
|
|
|
|
|
@total_ordering
|
|
class Version:
|
|
"""
|
|
Tolerant version comparator for real-world pipelines.
|
|
|
|
Handles:
|
|
v1.2
|
|
3.19
|
|
3.19.0-260127
|
|
3.19.0-rc1
|
|
3.19.0-rc1-260127
|
|
3.19_final
|
|
build_42
|
|
anything with numbers in it
|
|
"""
|
|
|
|
_PRERELEASE_RE = re.compile(r"(rc|alpha|beta|a|b)", re.I)
|
|
|
|
def __init__(self, raw: str):
|
|
self.raw = raw
|
|
self.parts = tuple(int(n) for n in re.findall(r"\d+", raw))
|
|
self.is_prerelease = bool(self._PRERELEASE_RE.search(raw))
|
|
|
|
def __eq__(self, other):
|
|
if not isinstance(other, Version):
|
|
return NotImplemented
|
|
return self.parts == other.parts and self.is_prerelease == other.is_prerelease
|
|
|
|
def __lt__(self, other):
|
|
if not isinstance(other, Version):
|
|
return NotImplemented
|
|
|
|
# compare numeric parts first
|
|
if self.parts != other.parts:
|
|
return self.parts < other.parts
|
|
|
|
# stable > prerelease
|
|
return self.is_prerelease and not other.is_prerelease
|
|
|
|
def __repr__(self):
|
|
return f"Version({self.raw!r})"
|
|
|
|
|
|
# -------------------------------
|
|
# Micro helpers
|
|
# -------------------------------
|
|
|
|
|
|
def version_gt(v1, v2):
|
|
"""Greater than"""
|
|
return Version(v1) > Version(v2)
|
|
|
|
|
|
def version_lt(v1, v2):
|
|
"""Less than"""
|
|
return Version(v1) < Version(v2)
|
|
|
|
|
|
def version_eq(v1, v2):
|
|
"""Equal"""
|
|
return Version(v1) == Version(v2)
|
|
|
|
|
|
def compare_versions(v1, v2):
|
|
"""Compare two version strings.
|
|
|
|
Returns:
|
|
-1 if v1 < v2
|
|
0 if v1 == v2
|
|
1 if v1 > v2
|
|
"""
|
|
ver1 = Version(v1)
|
|
ver2 = Version(v2)
|
|
if ver1 < ver2:
|
|
return -1
|
|
elif ver1 > ver2:
|
|
return 1
|
|
else:
|
|
return 0
|