diff --git a/docs/changelog/1583.bugfix.rst b/docs/changelog/1583.bugfix.rst new file mode 100644 index 000000000..aa44088d3 --- /dev/null +++ b/docs/changelog/1583.bugfix.rst @@ -0,0 +1,2 @@ +Fix system python discovery mechanism when prefixes contain relative parts (e.g. ``..``) by resolving paths within the +python information query - by :user:`gaborbernat`. diff --git a/src/virtualenv/__main__.py b/src/virtualenv/__main__.py index 12d431a74..b7508203d 100644 --- a/src/virtualenv/__main__.py +++ b/src/virtualenv/__main__.py @@ -5,6 +5,8 @@ import sys from datetime import datetime +import six + def run(args=None, options=None): start = datetime.now() @@ -14,14 +16,18 @@ def run(args=None, options=None): if args is None: args = sys.argv[1:] try: - run_via_cli(args, options) + session = run_via_cli(args, options) + logging.warning( + "created virtual environment in %.0fms %s with seeder %s", + (datetime.now() - start).total_seconds() * 1000, + six.ensure_text(str(session.creator)), + six.ensure_text(str(session.seeder)), + ) except ProcessCallFailed as exception: print("subprocess call failed for {}".format(exception.cmd)) print(exception.out, file=sys.stdout, end="") print(exception.err, file=sys.stderr, end="") raise SystemExit(exception.code) - finally: - logging.info("done in %.0fms", (datetime.now() - start).total_seconds() * 1000) def run_with_catch(args=None): diff --git a/src/virtualenv/discovery/py_info.py b/src/virtualenv/discovery/py_info.py index 211778c45..8e520ba0d 100644 --- a/src/virtualenv/discovery/py_info.py +++ b/src/virtualenv/discovery/py_info.py @@ -35,6 +35,9 @@ def __init__(self): def u(v): return v.decode("utf-8") if isinstance(v, bytes) else v + def abs_path(v): + return None if v is None else os.path.abspath(v) # unroll relative elements from path (e.g. ..) + # qualifies the python self.platform = u(sys.platform) self.implementation = u(platform.python_implementation()) @@ -49,16 +52,16 @@ def u(v): self.os = u(os.name) # information about the prefix - determines python home - self.prefix = u(getattr(sys, "prefix", None)) # prefix we think - self.base_prefix = u(getattr(sys, "base_prefix", None)) # venv - self.real_prefix = u(getattr(sys, "real_prefix", None)) # old virtualenv + self.prefix = u(abs_path(getattr(sys, "prefix", None))) # prefix we think + self.base_prefix = u(abs_path(getattr(sys, "base_prefix", None))) # venv + self.real_prefix = u(abs_path(getattr(sys, "real_prefix", None))) # old virtualenv # information about the exec prefix - dynamic stdlib modules - self.base_exec_prefix = u(getattr(sys, "base_exec_prefix", None)) - self.exec_prefix = u(getattr(sys, "exec_prefix", None)) + self.base_exec_prefix = u(abs_path(getattr(sys, "base_exec_prefix", None))) + self.exec_prefix = u(abs_path(getattr(sys, "exec_prefix", None))) - self.executable = u(sys.executable) # the executable we were invoked via - self.original_executable = u(self.executable) # the executable as known by the interpreter + self.executable = u(abs_path(sys.executable)) # the executable we were invoked via + self.original_executable = u(abs_path(self.executable)) # the executable as known by the interpreter self.system_executable = self._fast_get_system_executable() # the executable we are based of (if available) try: @@ -413,10 +416,6 @@ def _find_possible_folders(self, inside_folder): # or at root level candidate_folder[inside_folder] = None - if self.executable.startswith(self.prefix): - binary_within = os.path.relpath(os.path.dirname(self.executable), self.prefix) - candidate_folder[os.path.join(inside_folder, binary_within)] = None - return list(candidate_folder.keys()) def _find_possible_exe_names(self): diff --git a/src/virtualenv/run/__init__.py b/src/virtualenv/run/__init__.py index 309e33b26..ed7f6ef9b 100644 --- a/src/virtualenv/run/__init__.py +++ b/src/virtualenv/run/__init__.py @@ -2,8 +2,6 @@ import logging -import six - from ..config.cli.parser import VirtualEnvConfigParser from ..report import LEVELS, setup_report from ..session import Session @@ -22,12 +20,6 @@ def run_via_cli(args, options=None): """ session = session_via_cli(args, options) session.run() - - logging.warning( - "created virtual environment %s with seeder %s", - six.ensure_text(str(session.creator)), - six.ensure_text(str(session.seeder)), - ) return session