Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/virtualenv/discovery/py_spec.py @ 1:56ad4e20f292 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:32:28 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:d30785e31577 | 1:56ad4e20f292 |
|---|---|
| 1 """A Python specification is an abstract requirement definition of a interpreter""" | |
| 2 from __future__ import absolute_import, unicode_literals | |
| 3 | |
| 4 import os | |
| 5 import re | |
| 6 import sys | |
| 7 from collections import OrderedDict | |
| 8 | |
| 9 from virtualenv.info import fs_is_case_sensitive | |
| 10 from virtualenv.util.six import ensure_str | |
| 11 | |
| 12 PATTERN = re.compile(r"^(?P<impl>[a-zA-Z]+)?(?P<version>[0-9.]+)?(?:-(?P<arch>32|64))?$") | |
| 13 IS_WIN = sys.platform == "win32" | |
| 14 | |
| 15 | |
| 16 class PythonSpec(object): | |
| 17 """Contains specification about a Python Interpreter""" | |
| 18 | |
| 19 def __init__(self, str_spec, implementation, major, minor, micro, architecture, path): | |
| 20 self.str_spec = str_spec | |
| 21 self.implementation = implementation | |
| 22 self.major = major | |
| 23 self.minor = minor | |
| 24 self.micro = micro | |
| 25 self.architecture = architecture | |
| 26 self.path = path | |
| 27 | |
| 28 @classmethod | |
| 29 def from_string_spec(cls, string_spec): | |
| 30 impl, major, minor, micro, arch, path = None, None, None, None, None, None | |
| 31 if os.path.isabs(string_spec): | |
| 32 path = string_spec | |
| 33 else: | |
| 34 ok = False | |
| 35 match = re.match(PATTERN, string_spec) | |
| 36 if match: | |
| 37 | |
| 38 def _int_or_none(val): | |
| 39 return None if val is None else int(val) | |
| 40 | |
| 41 try: | |
| 42 groups = match.groupdict() | |
| 43 version = groups["version"] | |
| 44 if version is not None: | |
| 45 versions = tuple(int(i) for i in version.split(".") if i) | |
| 46 if len(versions) > 3: | |
| 47 raise ValueError | |
| 48 if len(versions) == 3: | |
| 49 major, minor, micro = versions | |
| 50 elif len(versions) == 2: | |
| 51 major, minor = versions | |
| 52 elif len(versions) == 1: | |
| 53 version_data = versions[0] | |
| 54 major = int(str(version_data)[0]) # first digit major | |
| 55 if version_data > 9: | |
| 56 minor = int(str(version_data)[1:]) | |
| 57 ok = True | |
| 58 except ValueError: | |
| 59 pass | |
| 60 else: | |
| 61 impl = groups["impl"] | |
| 62 if impl == "py" or impl == "python": | |
| 63 impl = "CPython" | |
| 64 arch = _int_or_none(groups["arch"]) | |
| 65 | |
| 66 if not ok: | |
| 67 path = string_spec | |
| 68 | |
| 69 return cls(string_spec, impl, major, minor, micro, arch, path) | |
| 70 | |
| 71 def generate_names(self): | |
| 72 impls = OrderedDict() | |
| 73 if self.implementation: | |
| 74 # first consider implementation as it is | |
| 75 impls[self.implementation] = False | |
| 76 if fs_is_case_sensitive(): | |
| 77 # for case sensitive file systems consider lower and upper case versions too | |
| 78 # trivia: MacBooks and all pre 2018 Windows-es were case insensitive by default | |
| 79 impls[self.implementation.lower()] = False | |
| 80 impls[self.implementation.upper()] = False | |
| 81 impls["python"] = True # finally consider python as alias, implementation must match now | |
| 82 version = self.major, self.minor, self.micro | |
| 83 try: | |
| 84 version = version[: version.index(None)] | |
| 85 except ValueError: | |
| 86 pass | |
| 87 for impl, match in impls.items(): | |
| 88 for at in range(len(version), -1, -1): | |
| 89 cur_ver = version[0:at] | |
| 90 spec = "{}{}".format(impl, ".".join(str(i) for i in cur_ver)) | |
| 91 yield spec, match | |
| 92 | |
| 93 @property | |
| 94 def is_abs(self): | |
| 95 return self.path is not None and os.path.isabs(self.path) | |
| 96 | |
| 97 def satisfies(self, spec): | |
| 98 """called when there's a candidate metadata spec to see if compatible - e.g. PEP-514 on Windows""" | |
| 99 if spec.is_abs and self.is_abs and self.path != spec.path: | |
| 100 return False | |
| 101 if spec.implementation is not None and spec.implementation.lower() != self.implementation.lower(): | |
| 102 return False | |
| 103 if spec.architecture is not None and spec.architecture != self.architecture: | |
| 104 return False | |
| 105 | |
| 106 for our, req in zip((self.major, self.minor, self.micro), (spec.major, spec.minor, spec.micro)): | |
| 107 if req is not None and our is not None and our != req: | |
| 108 return False | |
| 109 return True | |
| 110 | |
| 111 def __unicode__(self): | |
| 112 return "{}({})".format( | |
| 113 type(self).__name__, | |
| 114 ", ".join( | |
| 115 "{}={}".format(k, getattr(self, k)) | |
| 116 for k in ("implementation", "major", "minor", "micro", "architecture", "path") | |
| 117 if getattr(self, k) is not None | |
| 118 ), | |
| 119 ) | |
| 120 | |
| 121 def __repr__(self): | |
| 122 return ensure_str(self.__unicode__()) |
