Update pythonfinder for resilient parsing

Signed-off-by: Dan Ryan <dan@danryan.co>
This commit is contained in:
Dan Ryan
2018-11-19 21:01:11 -05:00
parent 26677830ae
commit 14d69fe07e
2 changed files with 37 additions and 46 deletions
+5 -44
View File
@@ -10,7 +10,7 @@ from collections import defaultdict
import attr
from packaging.version import Version
from packaging.version import Version, LegacyVersion
from packaging.version import parse as parse_version
from vistir.compat import Path
@@ -355,49 +355,10 @@ class PythonVersion(object):
:rtype: dict.
"""
is_debug = False
if version.endswith("-debug"):
is_debug = True
version, _, _ = version.rpartition("-")
try:
version = parse_version(str(version))
except TypeError:
try:
version_dict = parse_python_version(str(version))
except Exception:
raise ValueError("Unable to parse version: %s" % version)
else:
if not version_dict:
raise ValueError("Not a valid python version: %r" % version)
major = int(version_dict.get("major"))
minor = int(version_dict.get("minor"))
patch = version_dict.get("patch")
if patch:
patch = int(patch)
version = ".".join([v for v in [major, minor, patch] if v is not None])
version = parse_version(version)
else:
if not version or not version.release:
raise ValueError("Not a valid python version: %r" % version)
if len(version.release) >= 3:
major, minor, patch = version.release[:3]
elif len(version.release) == 2:
major, minor = version.release
patch = None
else:
major = version.release[0]
minor = None
patch = None
return {
"major": major,
"minor": minor,
"patch": patch,
"is_prerelease": version.is_prerelease,
"is_postrelease": version.is_postrelease,
"is_devrelease": version.is_devrelease,
"is_debug": is_debug,
"version": version,
}
version_dict = parse_python_version(str(version))
if not version_dict:
raise ValueError("Not a valid python version: %r" % version)
return version_dict
def get_architecture(self):
if self.architecture:
+32 -2
View File
@@ -25,7 +25,9 @@ except ImportError:
from backports.functools_lru_cache import lru_cache
version_re = re.compile(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.?(?P<patch>(?<=\.)[0-9]+)")
version_re = re.compile(r"(?P<major>\d+)\.(?P<minor>\d+)\.?(?P<patch>(?<=\.)[0-9]+)?\.?"
r"(?:(?P<prerel>[abc]|rc|dev)(?:(?P<prerelversion>\d+(?:\.\d+)*))?)"
r"?(?P<postdev>(\.post(?P<post>\d+))?(\.dev(?P<dev>\d+))?)?")
PYTHON_IMPLEMENTATIONS = (
@@ -66,10 +68,38 @@ def get_python_version(path):
@lru_cache(maxsize=1024)
def parse_python_version(version_str):
from packaging.version import parse as parse_version
is_debug = False
if version_str.endswith("-debug"):
is_debug = True
version_str, _, _ = version.rpartition("-")
m = version_re.match(version_str)
if not m:
raise InvalidPythonVersion("%s is not a python version" % version_str)
return m.groupdict()
version_dict = m.groupdict()
major = int(version_dict.get("major"))
minor = int(version_dict.get("minor"))
patch = version_dict.get("patch")
is_postrelease = True if version_dict.get("post") else False
is_prerelease = True if version_dict.get("prerel") else False
is_devrelease = True if version_dict.get("dev") else False
if patch:
patch = int(patch)
try:
version = parse_version(version_str)
except TypeError:
version_parts = [str(v) for v in [major, minor, patch] if v is not None]
version = parse_version(".".join(v))
return {
"major": major,
"minor": minor,
"patch": patch,
"is_postrelease": is_postrelease,
"is_prerelease": is_prerelease,
"is_devrelease": is_devrelease,
"is_debug": is_debug,
"version": version
}
def optional_instance_of(cls):