Skip to content

Commit

Permalink
fix system executable discovery (#1550)
Browse files Browse the repository at this point in the history
* fix system executable discovery

Signed-off-by: Bernat Gabor <[email protected]>

* time to eat our own dogfood

Signed-off-by: Bernat Gabor <[email protected]>

* seems Path.absolute should not be used

Signed-off-by: Bernat Gabor <[email protected]>
  • Loading branch information
gaborbernat authored Feb 10, 2020
1 parent 5c9b624 commit 2378b50
Show file tree
Hide file tree
Showing 9 changed files with 24 additions and 10 deletions.
6 changes: 6 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ jobs:
pathtoPublish: $(Build.ArtifactStagingDirectory)
ArtifactName: virtualenv.pyz
before:
- script: '$(toxPython.pythonLocation)/python -m pip install "virtualenv < 20"'
displayName: pypy3 tox needs fix to accomodate separate bin and Script
condition: and(succeeded(), eq(variables['image_name'], 'windows'), in(variables['TOXENV'], 'pypy3'))
- script: '$(toxPython.pythonLocation)/python -m pip install .'
displayName: tox uses this virtualenv (eat our own dogfood)
condition: not(and(succeeded(), eq(variables['image_name'], 'windows'), in(variables['TOXENV'], 'pypy3')))
- script: 'sudo apt-get update -y && sudo apt-get install fish csh'
condition: and(succeeded(), eq(variables['image_name'], 'linux'), in(variables['TOXENV'], 'py38', 'py37', 'py36', 'py35', 'py27', 'pypy', 'pypy3'))
displayName: install fish and csh via apt-get
Expand Down
1 change: 1 addition & 0 deletions docs/changelog/1552.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Virtual environments created via relative path on Windows creates bad console executables - by :user:`gaborbernat`.
2 changes: 2 additions & 0 deletions docs/changelog/1553.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Seems sometimes venvs created set their base executable to themselves; we accept these without question, so we handle
virtual environments as system pythons causing issues - by :user:`gaborbernat`.
4 changes: 2 additions & 2 deletions src/virtualenv/create/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from virtualenv.util.zipapp import ensure_file_on_disk
from virtualenv.version import __version__

HERE = Path(__file__).absolute().parent
HERE = Path(os.path.abspath(__file__)).parent
DEBUG_SCRIPT = HERE / "debug.py"


Expand Down Expand Up @@ -131,7 +131,7 @@ def non_write_able(dest, value):
# pre 3.6 resolve is always strict, aka must exists, sidestep by using os.path operation
dest = Path(os.path.realpath(raw_value))
else:
dest = value.resolve()
dest = Path(os.path.abspath(str(value))).resolve() # on Windows absolute does not imply resolve so use both
value = dest
while dest:
if dest.exists():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from ..via_global_self_do import ViaGlobalRefVirtualenvBuiltin

HERE = Path(__file__).absolute().parent
HERE = Path(os.path.abspath(__file__)).parent


@six.add_metaclass(abc.ABCMeta)
Expand Down
3 changes: 2 additions & 1 deletion src/virtualenv/discovery/cached_py_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import json
import logging
import os
import pipes
import sys
from collections import OrderedDict
Expand Down Expand Up @@ -99,7 +100,7 @@ def _get_fs_path():


def _run_subprocess(cls, exe):
resolved_path = Path(__file__).parent.absolute().absolute() / "py_info.py"
resolved_path = Path(os.path.abspath(__file__)).parent / "py_info.py"
with ensure_file_on_disk(resolved_path) as resolved_path:
cmd = [exe, "-s", str(resolved_path)]

Expand Down
3 changes: 2 additions & 1 deletion src/virtualenv/discovery/py_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ def _fast_get_system_executable(self):
if self.real_prefix is None:
base_executable = getattr(sys, "_base_executable", None) # some platforms may set this to help us
if base_executable is not None: # use the saved system executable if present
return base_executable
if sys.executable != base_executable: # we know we're in a virtual environment, cannot be us
return base_executable
return None # in this case we just can't tell easily without poking around FS and calling them, bail
# if we're not in a virtual environment, this is already a system python, so return the original executable
# note we must choose the original and not the pure executable as shim scripts might throw us off
Expand Down
3 changes: 0 additions & 3 deletions src/virtualenv/util/path/_pathlib/via_os_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ def __hash__(self):
def exists(self):
return os.path.exists(self._path)

def absolute(self):
return Path(os.path.abspath(self._path))

@property
def parent(self):
return Path(os.path.abspath(os.path.join(self._path, os.path.pardir)))
Expand Down
10 changes: 8 additions & 2 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import six

from virtualenv.__main__ import run
from virtualenv.create.creator import DEBUG_SCRIPT, get_env_debug_info
from virtualenv.create.creator import DEBUG_SCRIPT, Creator, get_env_debug_info
from virtualenv.discovery.builtin import get_interpreter
from virtualenv.discovery.py_info import PythonInfo
from virtualenv.info import IS_PYPY, fs_supports_symlink
Expand Down Expand Up @@ -69,7 +69,7 @@ def test_destination_not_write_able(tmp_path, capsys):
def cleanup_sys_path(paths):
from virtualenv.create.creator import HERE

paths = [Path(i).absolute() for i in paths]
paths = [Path(os.path.abspath(i)) for i in paths]
to_remove = [Path(HERE)]
if os.environ.get(str("PYCHARM_HELPERS_DIR")):
to_remove.append(Path(os.environ[str("PYCHARM_HELPERS_DIR")]).parent)
Expand Down Expand Up @@ -291,3 +291,9 @@ def create(count):
thread.start()
for thread in threads:
thread.join()


def test_creator_input_passed_is_abs(tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
result = Creator.validate_dest("venv")
assert str(result) == str(tmp_path / "venv")

0 comments on commit 2378b50

Please sign in to comment.