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__()) |