def _key(v):
    core, _, pre = v.partition('-')
    nums = tuple(int(x) for x in core.split('.'))
    return nums, pre

def _cmp_id(a, b):
    an, bn = a.isdigit(), b.isdigit()
    if an and bn:
        return (int(a) > int(b)) - (int(a) < int(b))
    if an:
        return -1  # numeric identifiers have lower precedence than alphanumeric
    if bn:
        return 1
    return (a > b) - (a < b)

def _cmp_pre(p, q):
    # no prerelease > has prerelease
    if not p:
        return 1 if q else 0
    if not q:
        return -1
    pa, qa = p.split('.'), q.split('.')
    for x, y in zip(pa, qa):
        c = _cmp_id(x, y)
        if c:
            return c
    return (len(pa) > len(qa)) - (len(pa) < len(qa))

def compare_semver(a, b):
    na, pa = _key(a)
    nb, pb = _key(b)
    for x, y in zip(na, nb):
        if x != y:
            return 1 if x > y else -1
    return _cmp_pre(pa, pb)
