Skip to content

Commit

Permalink
CentOs support
Browse files Browse the repository at this point in the history
Instead of hard coding patterns and guessing let's ask the host python
via the sysconfig.

Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
  • Loading branch information
gaborbernat committed Jan 17, 2020
1 parent 888e051 commit 8b3132f
Show file tree
Hide file tree
Showing 23 changed files with 190 additions and 206 deletions.
2 changes: 1 addition & 1 deletion src/virtualenv/activation/python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ def templates(self):

def replacements(self, creator, dest_folder):
replacements = super(PythonActivator, self).replacements(creator, dest_folder)
site_dump = json.dumps([os.path.relpath(str(i), str(dest_folder)) for i in creator.site_packages], indent=2)
site_dump = json.dumps(list({os.path.relpath(str(i), str(dest_folder)) for i in creator.libs}), indent=2)
replacements.update({"__SITE_PACKAGES__": site_dump})
return replacements
2 changes: 1 addition & 1 deletion src/virtualenv/activation/via_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def replacements(self, creator, dest_folder):
"__VIRTUAL_PROMPT__": "" if self.flag_prompt is None else self.flag_prompt,
"__VIRTUAL_ENV__": six.ensure_text(str(creator.dest_dir)),
"__VIRTUAL_NAME__": creator.env_name,
"__BIN_NAME__": six.ensure_text(str(creator.bin_name)),
"__BIN_NAME__": six.ensure_text(str(creator.bin_dir.relative_to(creator.dest_dir))),
"__PATH_SEP__": os.pathsep,
}

Expand Down
16 changes: 0 additions & 16 deletions src/virtualenv/interpreters/create/builtin_way.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,6 @@
class VirtualenvBuiltin(ViaGlobalRefApi):
"""A creator that does operations itself without delegation"""

@property
def bin_name(self):
raise NotImplementedError

@property
def bin_dir(self):
return self.dest_dir / self.bin_name

@property
def lib_dir(self):
raise NotImplementedError

@property
def site_packages(self):
return [self.lib_dir / "site-packages"]

@property
def exe_name(self):
raise NotImplementedError
Expand Down
24 changes: 0 additions & 24 deletions src/virtualenv/interpreters/create/cpython/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,6 @@ def exe_base(self):
class CPythonPosix(CPython, PosixSupports):
"""Create a CPython virtual environment on POSIX platforms"""

@property
def bin_name(self):
return "bin"

@property
def lib_name(self):
return "lib"

@property
def lib_base(self):
return Path(self.lib_name) / self.interpreter.python_name

def link_exe(self):
host = Path(self.interpreter.system_executable)
major, minor = self.interpreter.version_info.major, self.interpreter.version_info.minor
Expand All @@ -44,18 +32,6 @@ def link_exe(self):

@six.add_metaclass(abc.ABCMeta)
class CPythonWindows(CPython, WindowsSupports):
@property
def bin_name(self):
return "Scripts"

@property
def lib_name(self):
return "Lib"

@property
def lib_base(self):
return Path(self.lib_name)

def link_exe(self):
host = Path(self.interpreter.system_executable)
return {p: [p.name] for p in (host.parent / n for n in ("python.exe", "pythonw.exe", host.name)) if p.exists()}
49 changes: 49 additions & 0 deletions src/virtualenv/interpreters/create/creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,55 @@ def __init__(self, options, interpreter):
self.clear = options.clear
self.pyenv_cfg = PyEnvCfg.from_folder(self.dest_dir)

self._stdlib = None
self._system_stdlib = None
self._conf_vars = None

@property
def bin_dir(self):
return self.script_dir

@property
def script_dir(self):
return self.dest_dir / Path(self.interpreter.distutils_install["scripts"])

@property
def purelib(self):
return self.dest_dir / self.interpreter.distutils_install["purelib"]

@property
def platlib(self):
return self.dest_dir / self.interpreter.distutils_install["platlib"]

@property
def libs(self):
return list({self.platlib, self.purelib})

@property
def stdlib(self):
if self._stdlib is None:
self._stdlib = Path(self.interpreter.sysconfig_path("stdlib", config_var=self._config_vars))
return self._stdlib

@property
def system_stdlib(self):
if self._system_stdlib is None:
conf_vars = self._calc_config_vars(self.interpreter.system_prefix)
self._system_stdlib = Path(self.interpreter.sysconfig_path("stdlib", conf_vars))
return self._system_stdlib

@property
def _config_vars(self):
if self._conf_vars is None:
self._conf_vars = self._calc_config_vars(six.ensure_text(str(self.dest_dir)))
return self._conf_vars

def _calc_config_vars(self, to):
return {
k: (to if v.startswith(self.interpreter.prefix) else v)
for k, v in self.interpreter.sysconfig_config_vars.items()
}

def __repr__(self):
return six.ensure_str(self.__unicode__())

Expand Down
8 changes: 8 additions & 0 deletions src/virtualenv/interpreters/create/debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ def run():
except ImportError as exception: # pragma: no cover
result["datetime"] = repr(exception) # pragma: no cover

try:
# noinspection PyUnresolvedReferences
import math # site

result["math"] = repr(math)
except ImportError as exception: # pragma: no cover
result["math"] = repr(exception) # pragma: no cover

# try to print out, this will validate if other core modules are available (json in this case)
try:
import json
Expand Down
4 changes: 0 additions & 4 deletions src/virtualenv/interpreters/create/pypy/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ class PyPy(ViaGlobalRefVirtualenvBuiltin):
def supports(cls, interpreter):
return interpreter.implementation == "PyPy" and super(PyPy, cls).supports(interpreter)

@property
def site_packages(self):
return [self.dest_dir / "site-packages"]

def link_exe(self):
host = Path(self.interpreter.system_executable)
return {host: sorted("{}{}".format(name, self.suffix) for name in self.exe_names())}
Expand Down
25 changes: 6 additions & 19 deletions src/virtualenv/interpreters/create/pypy/pypy2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from virtualenv.interpreters.create.support import PosixSupports, WindowsSupports
from virtualenv.interpreters.create.via_global_ref.python2 import Python2
from virtualenv.util.path import Path

from .common import PyPy

Expand All @@ -19,22 +18,18 @@ class PyPy2(PyPy, Python2):
def exe_base(self):
return "pypy"

@property
def lib_name(self):
return "lib-python"

@property
def lib_pypy(self):
return self.dest_dir / "lib_pypy"

@property
def lib_base(self):
return Path(self.lib_name) / self.interpreter.version_release_str
def _calc_config_vars(self, to):
base = super(PyPy, self)._calc_config_vars(to)
# for some reason pypy seems to provide the wrong information for implementation_lower, fix it
base["implementation_lower"] = "python"
return base

def ensure_directories(self):
dirs = super(PyPy, self).ensure_directories()
dirs.add(self.lib_pypy)
return dirs
return super(PyPy, self).ensure_directories() | {self.lib_pypy}

def modules(self):
return [
Expand All @@ -51,10 +46,6 @@ def modules(self):
class PyPy2Posix(PyPy2, PosixSupports):
"""PyPy 2 on POSIX"""

@property
def bin_name(self):
return "bin"

def modules(self):
return super(PyPy2Posix, self).modules() + ["posixpath"]

Expand All @@ -66,10 +57,6 @@ def _shared_libs(self):
class Pypy2Windows(PyPy2, WindowsSupports):
"""PyPy 2 on Windows"""

@property
def bin_name(self):
return "Scripts"

def modules(self):
return super(Pypy2Windows, self).modules() + ["ntpath"]

Expand Down
43 changes: 12 additions & 31 deletions src/virtualenv/interpreters/create/pypy/pypy3.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,67 +5,48 @@
import six

from virtualenv.interpreters.create.support import PosixSupports, Python3Supports, WindowsSupports
from virtualenv.util.path import Path

from .common import PyPy


@six.add_metaclass(abc.ABCMeta)
class PyPy3(PyPy, Python3Supports):
""""""

@property
def exe_base(self):
return "pypy3"

@property
def stdlib(self):
"""
PyPy3 seems to respect sysconfig only for the host python...
virtual environments purelib is instead lib/pythonx.y
"""
return self.dest_dir / "lib" / "python{}".format(self.interpreter.version_release_str) / "site-packages"

def exe_names(self):
base = super(PyPy3, self).exe_names()
base.add("pypy")
return base

def ensure_directories(self):
dirs = super(PyPy, self).ensure_directories()
dirs.add(self.lib_dir / "site-packages")
return dirs


class PyPy3Posix(PyPy3, PosixSupports):
"""PyPy 2 on POSIX"""

@property
def bin_name(self):
return "bin"

@property
def lib_name(self):
return "lib"

@property
def lib_base(self):
return Path(self.lib_name) / self.interpreter.python_name

@property
def _shared_libs(self):
return ["libpypy3-c.so", "libpypy3-c.dylib"]

def _shared_lib_to(self):
return super(PyPy3, self)._shared_lib_to() + [self.dest_dir / self.lib_name]
return super(PyPy3, self)._shared_lib_to() + [self.stdlib.parent.parent]


class Pypy3Windows(PyPy3, WindowsSupports):
"""PyPy 2 on Windows"""

@property
def bin_name(self):
return "Scripts"

@property
def lib_name(self):
return "Lib"

@property
def lib_base(self):
return Path(self.lib_name)
def bin_dir(self):
"""PyPy3 needs to fallback to pypy definition"""
return self.dest_dir / "Scripts"

@property
def _shared_libs(self):
Expand Down
38 changes: 10 additions & 28 deletions src/virtualenv/interpreters/create/venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@

class Venv(ViaGlobalRefApi):
def __init__(self, options, interpreter):
self.builtin_way = options.builtin_way
super(Venv, self).__init__(options, interpreter)
self.can_be_inline = interpreter is CURRENT and interpreter.executable == interpreter.system_executable
self._context = None
self.builtin_way = options.builtin_way

def _args(self):
return super(Venv, self)._args() + (
Expand All @@ -33,9 +33,8 @@ def create(self):
else:
self.create_via_sub_process()
# TODO: cleanup activation scripts
if self.builtin_way is not None:
for site_package in self.builtin_way.site_packages:
ensure_dir(site_package)
for lib in self.libs:
ensure_dir(lib)

def create_inline(self):
from venv import EnvBuilder
Expand Down Expand Up @@ -66,27 +65,10 @@ def set_pyenv_cfg(self):
super(Venv, self).set_pyenv_cfg()
self.pyenv_cfg.update(venv_content)

def _proxy_builtin_way(self, key):
if self.builtin_way is None:
return None
return getattr(self.builtin_way, key)

@property
def exe(self):
return self._proxy_builtin_way("exe")

@property
def site_packages(self):
return self._proxy_builtin_way("site_packages")

@property
def bin_dir(self):
return self._proxy_builtin_way("bin_dir")

@property
def bin_name(self):
return self._proxy_builtin_way("bin_name")

@property
def lib_dir(self):
return self._proxy_builtin_way("lib_dir")
def __getattribute__(self, item):
builtin = object.__getattribute__(self, "builtin_way")
if builtin is not None and hasattr(builtin, item):
element = getattr(builtin, item)
if not callable(element):
return element
return object.__getattribute__(self, item)
14 changes: 7 additions & 7 deletions src/virtualenv/interpreters/create/via_global_ref/python2.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ def fixup_python2(self):
self.add_module(module)
# 2. install a patched site-package, the default Python 2 site.py is not smart enough to understand pyvenv.cfg,
# so we inject a small shim that can do this
site_py = self.lib_dir / "site.py"
relative_site_packages = [
os.path.relpath(six.ensure_text(str(s)), six.ensure_text(str(site_py))) for s in self.site_packages
]
site_py = self.stdlib / "site.py"
custom_site = get_custom_site()
if IS_ZIPAPP:
custom_site_text = read_from_zipapp(custom_site)
else:
custom_site_text = custom_site.read_text()
site_py.write_text(custom_site_text.replace("___EXPECTED_SITE_PACKAGES___", json.dumps(relative_site_packages)))
expected = json.dumps(
[os.path.relpath(six.ensure_text(str(i)), six.ensure_text(str(site_py))) for i in self.libs]
)
site_py.write_text(custom_site_text.replace("___EXPECTED_SITE_PACKAGES___", expected))

@abc.abstractmethod
def modules(self):
Expand All @@ -48,10 +48,10 @@ def add_exe_method(self):
def add_module(self, req):
for ext in ["py", "pyc"]:
file_path = "{}.{}".format(req, ext)
self.copier(self.system_stdlib / file_path, self.lib_dir / file_path)
self.copier(self.system_stdlib / file_path, self.stdlib / file_path)

def add_folder(self, folder):
self.copier(self.system_stdlib / folder, self.lib_dir / folder)
self.copier(self.system_stdlib / folder, self.stdlib / folder)


def get_custom_site():
Expand Down

0 comments on commit 8b3132f

Please sign in to comment.