Mercurial > repos > shellac > sam_consensus_v3
diff env/lib/python3.9/site-packages/virtualenv/discovery/builtin.py @ 0:4f3585e2f14b draft default tip
"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author | shellac |
---|---|
date | Mon, 22 Mar 2021 18:12:50 +0000 (2021-03-22) |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/lib/python3.9/site-packages/virtualenv/discovery/builtin.py Mon Mar 22 18:12:50 2021 +0000 @@ -0,0 +1,186 @@ +from __future__ import absolute_import, unicode_literals + +import logging +import os +import sys + +from virtualenv.info import IS_WIN +from virtualenv.util.six import ensure_str, ensure_text + +from .discover import Discover +from .py_info import PythonInfo +from .py_spec import PythonSpec + + +class Builtin(Discover): + def __init__(self, options): + super(Builtin, self).__init__(options) + self.python_spec = options.python if options.python else [sys.executable] + self.app_data = options.app_data + self.try_first_with = options.try_first_with + + @classmethod + def add_parser_arguments(cls, parser): + parser.add_argument( + "-p", + "--python", + dest="python", + metavar="py", + type=str, + action="append", + default=[], + help="interpreter based on what to create environment (path/identifier) " + "- by default use the interpreter where the tool is installed - first found wins", + ) + parser.add_argument( + "--try-first-with", + dest="try_first_with", + metavar="py_exe", + type=str, + action="append", + default=[], + help="try first these interpreters before starting the discovery", + ) + + def run(self): + for python_spec in self.python_spec: + result = get_interpreter(python_spec, self.try_first_with, self.app_data, self._env) + if result is not None: + return result + return None + + def __repr__(self): + return ensure_str(self.__unicode__()) + + def __unicode__(self): + spec = self.python_spec[0] if len(self.python_spec) == 1 else self.python_spec + return "{} discover of python_spec={!r}".format(self.__class__.__name__, spec) + + +def get_interpreter(key, try_first_with, app_data=None, env=None): + spec = PythonSpec.from_string_spec(key) + logging.info("find interpreter for spec %r", spec) + proposed_paths = set() + env = os.environ if env is None else env + for interpreter, impl_must_match in propose_interpreters(spec, try_first_with, app_data, env): + key = interpreter.system_executable, impl_must_match + if key in proposed_paths: + continue + logging.info("proposed %s", interpreter) + if interpreter.satisfies(spec, impl_must_match): + logging.debug("accepted %s", interpreter) + return interpreter + proposed_paths.add(key) + + +def propose_interpreters(spec, try_first_with, app_data, env=None): + # 0. try with first + env = os.environ if env is None else env + for py_exe in try_first_with: + path = os.path.abspath(py_exe) + try: + os.lstat(path) # Windows Store Python does not work with os.path.exists, but does for os.lstat + except OSError: + pass + else: + yield PythonInfo.from_exe(os.path.abspath(path), app_data, env=env), True + + # 1. if it's a path and exists + if spec.path is not None: + try: + os.lstat(spec.path) # Windows Store Python does not work with os.path.exists, but does for os.lstat + except OSError: + if spec.is_abs: + raise + else: + yield PythonInfo.from_exe(os.path.abspath(spec.path), app_data, env=env), True + if spec.is_abs: + return + else: + # 2. otherwise try with the current + yield PythonInfo.current_system(app_data), True + + # 3. otherwise fallback to platform default logic + if IS_WIN: + from .windows import propose_interpreters + + for interpreter in propose_interpreters(spec, app_data, env): + yield interpreter, True + # finally just find on path, the path order matters (as the candidates are less easy to control by end user) + paths = get_paths(env) + tested_exes = set() + for pos, path in enumerate(paths): + path = ensure_text(path) + logging.debug(LazyPathDump(pos, path, env)) + for candidate, match in possible_specs(spec): + found = check_path(candidate, path) + if found is not None: + exe = os.path.abspath(found) + if exe not in tested_exes: + tested_exes.add(exe) + interpreter = PathPythonInfo.from_exe(exe, app_data, raise_on_error=False, env=env) + if interpreter is not None: + yield interpreter, match + + +def get_paths(env): + path = env.get(str("PATH"), None) + if path is None: + try: + path = os.confstr("CS_PATH") + except (AttributeError, ValueError): + path = os.defpath + if not path: + paths = [] + else: + paths = [p for p in path.split(os.pathsep) if os.path.exists(p)] + return paths + + +class LazyPathDump(object): + def __init__(self, pos, path, env): + self.pos = pos + self.path = path + self.env = env + + def __repr__(self): + return ensure_str(self.__unicode__()) + + def __unicode__(self): + content = "discover PATH[{}]={}".format(self.pos, self.path) + if self.env.get(str("_VIRTUALENV_DEBUG")): # this is the over the board debug + content += " with =>" + for file_name in os.listdir(self.path): + try: + file_path = os.path.join(self.path, file_name) + if os.path.isdir(file_path) or not os.access(file_path, os.X_OK): + continue + except OSError: + pass + content += " " + content += file_name + return content + + +def check_path(candidate, path): + _, ext = os.path.splitext(candidate) + if sys.platform == "win32" and ext != ".exe": + candidate = candidate + ".exe" + if os.path.isfile(candidate): + return candidate + candidate = os.path.join(path, candidate) + if os.path.isfile(candidate): + return candidate + return None + + +def possible_specs(spec): + # 4. then maybe it's something exact on PATH - if it was direct lookup implementation no longer counts + yield spec.str_spec, False + # 5. or from the spec we can deduce a name on path that matches + for exe, match in spec.generate_names(): + yield exe, match + + +class PathPythonInfo(PythonInfo): + """"""