Skip to content

Commit

Permalink
Make aliases relative symlinks (#1610)
Browse files Browse the repository at this point in the history
  • Loading branch information
asottile authored Feb 13, 2020
1 parent eb80439 commit a446286
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 20 deletions.
1 change: 1 addition & 0 deletions docs/changelog/1596.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When aliasing interpreters, use relative symlinks - by :user:`asottile`.
12 changes: 6 additions & 6 deletions src/virtualenv/create/via_global_ref/builtin/ref.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

from six import add_metaclass

from virtualenv.info import PY3, fs_is_case_sensitive, fs_supports_symlink
from virtualenv.util.path import copy, link, make_exe, symlink
from virtualenv.info import fs_is_case_sensitive, fs_supports_symlink
from virtualenv.util.path import copy, make_exe, symlink
from virtualenv.util.six import ensure_text


Expand Down Expand Up @@ -95,9 +95,6 @@ def run(self, creator, symlinks):
method(self.src, dst)


alias_via = link if PY3 else (symlink if PathRef.FS_SUPPORTS_SYMLINK else copy)


class ExePathRefToDest(PathRefToDest, ExePathRef):
def __init__(self, src, targets, dest, must_copy=False):
ExePathRef.__init__(self, src)
Expand All @@ -119,5 +116,8 @@ def run(self, creator, symlinks):
link_file = bin_dir / extra
if link_file.exists():
link_file.unlink()
alias_via(dest, link_file)
if symlinks:
link_file.symlink_to(self.base)
else:
copy(self.src, link_file)
make_exe(link_file)
3 changes: 1 addition & 2 deletions src/virtualenv/util/path/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

from ._pathlib import Path
from ._permission import make_exe
from ._sync import copy, copytree, ensure_dir, link, symlink
from ._sync import copy, copytree, ensure_dir, symlink

__all__ = (
"ensure_dir",
"link",
"symlink",
"copy",
"copytree",
Expand Down
13 changes: 1 addition & 12 deletions src/virtualenv/util/path/_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@
import os
import shutil

from six import PY2, PY3
from six import PY2

from virtualenv.info import IS_CPYTHON, IS_WIN
from virtualenv.util.six import ensure_text

if PY3:
from os import link as os_link

if PY2 and IS_CPYTHON and IS_WIN: # CPython2 on Windows supports unicode paths if passed as unicode
norm = lambda src: ensure_text(str(src)) # noqa
else:
Expand Down Expand Up @@ -62,12 +59,6 @@ def copytree(src, dest):
shutil.copy(src_f, dest_f)


def link(src, dest):
ensure_safe_to_do(src, dest)
logging.debug("hard link %s", _Debug(src, dest.name))
os_link(norm(src), norm(dest))


class _Debug(object):
def __init__(self, src, dest):
self.src = src
Expand All @@ -83,8 +74,6 @@ def __str__(self):
"ensure_dir",
"symlink",
"copy",
"link",
"symlink",
"link",
"copytree",
)
20 changes: 20 additions & 0 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,26 @@ def list_to_str(iterable):

assert common, "\n".join(difflib.unified_diff(list_to_str(sys_path), list_to_str(system_sys_path)))

# test that the python executables in the bin directory are either:
# - files
# - absolute symlinks outside of the venv
# - relative symlinks inside of the venv
if sys.platform == "win32":
exes = ("python.exe",)
else:
# TODO: also test "python{}.{}" once fixed
exes = ("python", "python{}".format(sys.version_info[0]))
for exe in exes:
exe_path = result.creator.bin_dir / exe
assert exe_path.exists()
if not exe_path.is_symlink(): # option 1: a real file
continue # it was a file
link = os.readlink(str(exe_path))
if not os.path.isabs(link): # option 2: a relative symlink
continue
# option 3: an absolute symlink, should point outside the venv
assert not link.startswith(str(result.creator.dest))


@pytest.mark.skipif(not CURRENT.has_venv, reason="requires interpreter with venv")
def test_venv_fails_not_inline(tmp_path, capsys, mocker):
Expand Down

0 comments on commit a446286

Please sign in to comment.