Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/virtualenv/discovery/builtin.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 from __future__ import absolute_import, unicode_literals | |
2 | |
3 import logging | |
4 import os | |
5 import sys | |
6 | |
7 from virtualenv.info import IS_WIN | |
8 from virtualenv.util.six import ensure_str, ensure_text | |
9 | |
10 from .discover import Discover | |
11 from .py_info import PythonInfo | |
12 from .py_spec import PythonSpec | |
13 | |
14 | |
15 class Builtin(Discover): | |
16 def __init__(self, options): | |
17 super(Builtin, self).__init__(options) | |
18 self.python_spec = options.python | |
19 self.app_data = options.app_data | |
20 | |
21 @classmethod | |
22 def add_parser_arguments(cls, parser): | |
23 parser.add_argument( | |
24 "-p", | |
25 "--python", | |
26 dest="python", | |
27 metavar="py", | |
28 help="target interpreter for which to create a virtual (either absolute path or identifier string)", | |
29 default=sys.executable, | |
30 ) | |
31 | |
32 def run(self): | |
33 return get_interpreter(self.python_spec, self.app_data) | |
34 | |
35 def __repr__(self): | |
36 return ensure_str(self.__unicode__()) | |
37 | |
38 def __unicode__(self): | |
39 return "{} discover of python_spec={!r}".format(self.__class__.__name__, self.python_spec) | |
40 | |
41 | |
42 def get_interpreter(key, app_data=None): | |
43 spec = PythonSpec.from_string_spec(key) | |
44 logging.info("find interpreter for spec %r", spec) | |
45 proposed_paths = set() | |
46 for interpreter, impl_must_match in propose_interpreters(spec, app_data): | |
47 key = interpreter.system_executable, impl_must_match | |
48 if key in proposed_paths: | |
49 continue | |
50 logging.info("proposed %s", interpreter) | |
51 if interpreter.satisfies(spec, impl_must_match): | |
52 logging.debug("accepted %s", interpreter) | |
53 return interpreter | |
54 proposed_paths.add(key) | |
55 | |
56 | |
57 def propose_interpreters(spec, app_data): | |
58 # 1. if it's a path and exists | |
59 if spec.path is not None: | |
60 try: | |
61 os.lstat(spec.path) # Windows Store Python does not work with os.path.exists, but does for os.lstat | |
62 except OSError: | |
63 if spec.is_abs: | |
64 raise | |
65 else: | |
66 yield PythonInfo.from_exe(os.path.abspath(spec.path), app_data), True | |
67 if spec.is_abs: | |
68 return | |
69 else: | |
70 # 2. otherwise try with the current | |
71 yield PythonInfo.current_system(app_data), True | |
72 | |
73 # 3. otherwise fallback to platform default logic | |
74 if IS_WIN: | |
75 from .windows import propose_interpreters | |
76 | |
77 for interpreter in propose_interpreters(spec, app_data): | |
78 yield interpreter, True | |
79 # finally just find on path, the path order matters (as the candidates are less easy to control by end user) | |
80 paths = get_paths() | |
81 tested_exes = set() | |
82 for pos, path in enumerate(paths): | |
83 path = ensure_text(path) | |
84 logging.debug(LazyPathDump(pos, path)) | |
85 for candidate, match in possible_specs(spec): | |
86 found = check_path(candidate, path) | |
87 if found is not None: | |
88 exe = os.path.abspath(found) | |
89 if exe not in tested_exes: | |
90 tested_exes.add(exe) | |
91 interpreter = PathPythonInfo.from_exe(exe, app_data, raise_on_error=False) | |
92 if interpreter is not None: | |
93 yield interpreter, match | |
94 | |
95 | |
96 def get_paths(): | |
97 path = os.environ.get(str("PATH"), None) | |
98 if path is None: | |
99 try: | |
100 path = os.confstr("CS_PATH") | |
101 except (AttributeError, ValueError): | |
102 path = os.defpath | |
103 if not path: | |
104 paths = [] | |
105 else: | |
106 paths = [p for p in path.split(os.pathsep) if os.path.exists(p)] | |
107 return paths | |
108 | |
109 | |
110 class LazyPathDump(object): | |
111 def __init__(self, pos, path): | |
112 self.pos = pos | |
113 self.path = path | |
114 | |
115 def __repr__(self): | |
116 return ensure_str(self.__unicode__()) | |
117 | |
118 def __unicode__(self): | |
119 content = "discover PATH[{}]={}".format(self.pos, self.path) | |
120 if os.environ.get(str("_VIRTUALENV_DEBUG")): # this is the over the board debug | |
121 content += " with =>" | |
122 for file_name in os.listdir(self.path): | |
123 try: | |
124 file_path = os.path.join(self.path, file_name) | |
125 if os.path.isdir(file_path) or not os.access(file_path, os.X_OK): | |
126 continue | |
127 except OSError: | |
128 pass | |
129 content += " " | |
130 content += file_name | |
131 return content | |
132 | |
133 | |
134 def check_path(candidate, path): | |
135 _, ext = os.path.splitext(candidate) | |
136 if sys.platform == "win32" and ext != ".exe": | |
137 candidate = candidate + ".exe" | |
138 if os.path.isfile(candidate): | |
139 return candidate | |
140 candidate = os.path.join(path, candidate) | |
141 if os.path.isfile(candidate): | |
142 return candidate | |
143 return None | |
144 | |
145 | |
146 def possible_specs(spec): | |
147 # 4. then maybe it's something exact on PATH - if it was direct lookup implementation no longer counts | |
148 yield spec.str_spec, False | |
149 # 5. or from the spec we can deduce a name on path that matches | |
150 for exe, match in spec.generate_names(): | |
151 yield exe, match | |
152 | |
153 | |
154 class PathPythonInfo(PythonInfo): | |
155 """""" |