Download code/bugfind/bench/semverlite.py from viai957/align: direct link, hf CLI and curl.
- Browser
- Download file 2.29 kB
-
https://huggingface.co/viai957/align/resolve/main/code/bugfind/bench/semverlite.py
- Command line
-
hf download hf://viai957/align/code/bugfind/bench/semverlite.py
-
curl -L -o semverlite.py https://huggingface.co/viai957/align/resolve/main/code/bugfind/bench/semverlite.py
2.29 kB
| """Minimal Cargo-style semver parsing/matching (enough for RustSec version ranges).""" | |
| import re | |
| _V = re.compile(r"^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?(?:\+.*)?$") | |
| def parse(v): | |
| m = _V.match(v.strip()) | |
| if not m: | |
| raise ValueError(v) | |
| a, b, c, pre = m.groups() | |
| return (int(a), int(b or 0), int(c or 0)), pre | |
| def key(v): | |
| t, pre = parse(v) | |
| # prerelease sorts before release | |
| return (t, 0 if pre else 1, pre or "") | |
| def is_pre(v): | |
| return parse(v)[1] is not None | |
| def _parts(s): | |
| m = _V.match(s.strip()) | |
| a, b, c, pre = m.groups() | |
| return int(a), (None if b is None else int(b)), (None if c is None else int(c)), pre | |
| def _cmp_one(v, op, rhs): | |
| kv = key(v) | |
| kr = key(rhs) | |
| if op == "=": | |
| a, b, c, _ = _parts(rhs) | |
| t = kv[0] | |
| if b is None: | |
| return t[0] == a | |
| if c is None: | |
| return t[0] == a and t[1] == b | |
| return kv == kr | |
| if op == "<": | |
| return kv < kr | |
| if op == "<=": | |
| a, b, c, _ = _parts(rhs) | |
| if c is None: # "<= 1.2" means < 1.3 style; be permissive | |
| hi = (a, (b if b is not None else 0), 10**9) | |
| return kv[0] <= hi | |
| return kv <= kr | |
| if op == ">": | |
| return kv > kr | |
| if op == ">=": | |
| return kv >= kr | |
| if op == "^" or op == "": | |
| a, b, c, _ = _parts(rhs) | |
| lo = kr | |
| if a > 0 or b is None: | |
| hi = (a + 1, 0, 0) | |
| elif b > 0 or c is None: | |
| hi = (0, b + 1, 0) | |
| else: | |
| hi = (0, 0, c + 1) | |
| return kv >= lo and kv[0] < hi | |
| if op == "~": | |
| a, b, c, _ = _parts(rhs) | |
| hi = (a + 1, 0, 0) if b is None else (a, b + 1, 0) | |
| return kv >= kr and kv[0] < hi | |
| raise ValueError(op) | |
| _C = re.compile(r"^\s*(<=|>=|=|<|>|\^|~)?\s*(\S+)\s*$") | |
| def matches_req(v, req): | |
| """req: comma-separated comparator list; all must hold.""" | |
| for part in req.split(","): | |
| m = _C.match(part) | |
| if not m: | |
| raise ValueError(req) | |
| op, rhs = m.groups() | |
| if rhs.endswith(".*"): | |
| rhs, op = rhs[:-2], "=" | |
| if not _cmp_one(v, op or "", rhs): | |
| return False | |
| return True | |
| def matches_any(v, reqs): | |
| return any(matches_req(v, r) for r in reqs) | |