Your IP : 3.147.82.22
from __future__ import annotations
import logging
import os
from abc import ABC
from pathlib import Path
from virtualenv.create.creator import Creator, CreatorMeta
from virtualenv.info import fs_supports_symlink
class ViaGlobalRefMeta(CreatorMeta):
def __init__(self) -> None:
super().__init__()
self.copy_error = None
self.symlink_error = None
if not fs_supports_symlink():
self.symlink_error = "the filesystem does not supports symlink"
@property
def can_copy(self):
return not self.copy_error
@property
def can_symlink(self):
return not self.symlink_error
class ViaGlobalRefApi(Creator, ABC):
def __init__(self, options, interpreter) -> None:
super().__init__(options, interpreter)
self.symlinks = self._should_symlink(options)
self.enable_system_site_package = options.system_site
@staticmethod
def _should_symlink(options):
# Priority of where the option is set to follow the order: CLI, env var, file, hardcoded.
# If both set at same level prefers copy over symlink.
copies, symlinks = getattr(options, "copies", False), getattr(options, "symlinks", False)
copy_src, sym_src = options.get_source("copies"), options.get_source("symlinks")
for level in ["cli", "env var", "file", "default"]:
s_opt = symlinks if sym_src == level else None
c_opt = copies if copy_src == level else None
if s_opt is True and c_opt is True:
return False
if s_opt is True:
return True
if c_opt is True:
return False
return False # fallback to copy
@classmethod
def add_parser_arguments(cls, parser, interpreter, meta, app_data):
super().add_parser_arguments(parser, interpreter, meta, app_data)
parser.add_argument(
"--system-site-packages",
default=False,
action="store_true",
dest="system_site",
help="give the virtual environment access to the system site-packages dir",
)
if not meta.can_symlink and not meta.can_copy:
msg = "neither symlink or copy method supported"
raise RuntimeError(msg)
group = parser.add_mutually_exclusive_group()
if meta.can_symlink:
group.add_argument(
"--symlinks",
default=True,
action="store_true",
dest="symlinks",
help="try to use symlinks rather than copies, when symlinks are not the default for the platform",
)
if meta.can_copy:
group.add_argument(
"--copies",
"--always-copy",
default=not meta.can_symlink,
action="store_true",
dest="copies",
help="try to use copies rather than symlinks, even when symlinks are the default for the platform",
)
def create(self):
self.install_patch()
def install_patch(self):
text = self.env_patch_text()
if text:
pth = self.purelib / "_virtualenv.pth"
logging.debug("create virtualenv import hook file %s", pth)
pth.write_text("import _virtualenv", encoding="utf-8")
dest_path = self.purelib / "_virtualenv.py"
logging.debug("create %s", dest_path)
dest_path.write_text(text, encoding="utf-8")
def env_patch_text(self):
"""Patch the distutils package to not be derailed by its configuration files."""
with self.app_data.ensure_extracted(Path(__file__).parent / "_virtualenv.py") as resolved_path:
text = resolved_path.read_text(encoding="utf-8")
return text.replace('"__SCRIPT_DIR__"', repr(os.path.relpath(str(self.script_dir), str(self.purelib))))
def _args(self):
return [*super()._args(), ("global", self.enable_system_site_package)]
def set_pyenv_cfg(self):
super().set_pyenv_cfg()
self.pyenv_cfg["include-system-site-packages"] = "true" if self.enable_system_site_package else "false"
__all__ = [
"ViaGlobalRefApi",
"ViaGlobalRefMeta",
]