Skip to content

Instantly share code, notes, and snippets.

@jeetsukumaran
Created April 11, 2018 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeetsukumaran/6b5a0a4e62c1825c1afb2e9f957f6459 to your computer and use it in GitHub Desktop.
Save jeetsukumaran/6b5a0a4e62c1825c1afb2e9f957f6459 to your computer and use it in GitHub Desktop.
PEP 440 Python Versioning Compliance/Parsing
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import re
VERSION_PATTERN = r"""
v?
(?:
(?:(?P<epoch>[0-9]+)!)? # epoch
(?P<release>[0-9]+(?:\.[0-9]+)*) # release segment
(?P<pre> # pre-release
[-_\.]?
(?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview))
[-_\.]?
(?P<pre_n>[0-9]+)?
)?
(?P<post> # post release
(?:-(?P<post_n1>[0-9]+))
|
(?:
[-_\.]?
(?P<post_l>post|rev|r)
[-_\.]?
(?P<post_n2>[0-9]+)?
)
)?
(?P<dev> # dev release
[-_\.]?
(?P<dev_l>dev)
[-_\.]?
(?P<dev_n>[0-9]+)?
)?
)
(?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version
"""
_regex = re.compile(
r"^\s*" + VERSION_PATTERN + r"\s*$",
re.VERBOSE | re.IGNORECASE,
)
def is_canonical(version):
return re.match(r'^([1-9]\d*!)?(0|[1-9]\d*)(\.(0|[1-9]\d*))*((a|b|rc)(0|[1-9]\d*))?(\.post(0|[1-9]\d*))?(\.dev(0|[1-9]\d*))?$', version) is not None
def extract(version):
ok = is_canonical(version)
if not ok:
sys.exit("Not compliant")
m = _regex.match(version)
if m:
for key in ("epoch", "release", "pre", "pre_l", "pre_n", "post", "post_n1", "post_l", "post_n2", "dev", "dev_l", "dev_n", "local"):
print("{:>15}: {}".format(key, m.group(key)))
else:
print("No match")
version = sys.argv[1]
extract(version)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment