diff --git a/tests/lib/venv.py b/tests/lib/venv.py index cc94e29f254..eae5e2c0d36 100644 --- a/tests/lib/venv.py +++ b/tests/lib/venv.py @@ -2,7 +2,7 @@ import compileall import shutil -import sys +import sysconfig import textwrap import six @@ -32,16 +32,15 @@ def __init__(self, location, template=None, venv_type=None): self._create() def _update_paths(self): - home, lib, inc, bin = _virtualenv.path_locations(self.location) - self.bin = Path(bin) - self.site = Path(lib) / 'site-packages' - # Workaround for https://github.com/pypa/virtualenv/issues/306 - if hasattr(sys, "pypy_version_info"): - version_fmt = '{0}' if six.PY3 else '{0}.{1}' - version_dir = version_fmt.format(*sys.version_info) - self.lib = Path(home, 'lib-python', version_dir) - else: - self.lib = Path(lib) + paths = sysconfig.get_paths(vars={ + "installed_base": self.location, + "installed_platbase": self.location, + "base": self.location, + "platbase": self.location, + }) + self.bin = Path(paths["scripts"]) + self.site = Path(paths["purelib"]) + self.lib = Path(paths["stdlib"]) def __repr__(self): return "".format(self.location) @@ -50,10 +49,6 @@ def _create(self, clear=False): if clear: shutil.rmtree(self.location) if self._template: - # On Windows, calling `_virtualenv.path_locations(target)` - # will have created the `target` directory... - if sys.platform == 'win32' and self.location.exists(): - self.location.rmdir() # Clone virtual environment from template. shutil.copytree( self._template.location, self.location, symlinks=True @@ -63,88 +58,51 @@ def _create(self, clear=False): else: # Create a new virtual environment. if self._venv_type == 'virtualenv': - _virtualenv.create_environment( + _virtualenv.cli_run([ self.location, - no_pip=True, - no_wheel=True, - no_setuptools=True, - ) - self._fix_virtualenv_site_module() + "--no-pip", + "--no-wheel", + "--no-setuptools", + ]) elif self._venv_type == 'venv': builder = _venv.EnvBuilder() context = builder.ensure_directories(self.location) builder.create_configuration(context) builder.setup_python(context) self.site.mkdir(parents=True, exist_ok=True) + else: + raise ValueError("venv type must be 'virtualenv' or 'venv'") self.sitecustomize = self._sitecustomize self.user_site_packages = self._user_site_packages - def _fix_virtualenv_site_module(self): - # Patch `site.py` so user site work as expected. - site_py = self.lib / 'site.py' - with open(site_py) as fp: - site_contents = fp.read() - for pattern, replace in ( - ( - # Ensure enabling user site does not result in adding - # the real site-packages' directory to `sys.path`. - ( - '\ndef virtual_addsitepackages(known_paths):\n' - ), - ( - '\ndef virtual_addsitepackages(known_paths):\n' - ' return known_paths\n' - ), - ), - ( - # Fix sites ordering: user site must be added before system. - ( - '\n paths_in_sys = addsitepackages(paths_in_sys)' - '\n paths_in_sys = addusersitepackages(paths_in_sys)\n' - ), - ( - '\n paths_in_sys = addusersitepackages(paths_in_sys)' - '\n paths_in_sys = addsitepackages(paths_in_sys)\n' - ), - ), - ): - assert pattern in site_contents - site_contents = site_contents.replace(pattern, replace) - with open(site_py, 'w') as fp: - fp.write(site_contents) - # Make sure bytecode is up-to-date too. - assert compileall.compile_file(str(site_py), quiet=1, force=True) - def _customize_site(self): - contents = '' - if self._venv_type == 'venv': - # Enable user site (before system). - contents += textwrap.dedent( - ''' - import os, site, sys - - if not os.environ.get('PYTHONNOUSERSITE', False): - - site.ENABLE_USER_SITE = True - - # First, drop system-sites related paths. - original_sys_path = sys.path[:] - known_paths = set() - for path in site.getsitepackages(): - site.addsitedir(path, known_paths=known_paths) - system_paths = sys.path[len(original_sys_path):] - for path in system_paths: - if path in original_sys_path: - original_sys_path.remove(path) - sys.path = original_sys_path - - # Second, add user-site. - site.addsitedir(site.getusersitepackages()) - - # Third, add back system-sites related paths. - for path in site.getsitepackages(): - site.addsitedir(path) - ''').strip() + # Enable user site (before system). + contents = textwrap.dedent( + ''' + import os, site, sys + + if not os.environ.get('PYTHONNOUSERSITE', False): + + site.ENABLE_USER_SITE = True + + # First, drop system-sites related paths. + original_sys_path = sys.path[:] + known_paths = set() + for path in site.getsitepackages(): + site.addsitedir(path, known_paths=known_paths) + system_paths = sys.path[len(original_sys_path):] + for path in system_paths: + if path in original_sys_path: + original_sys_path.remove(path) + sys.path = original_sys_path + + # Second, add user-site. + site.addsitedir(site.getusersitepackages()) + + # Third, add back system-sites related paths. + for path in site.getsitepackages(): + site.addsitedir(path) + ''').strip() if self._sitecustomize is not None: contents += '\n' + self._sitecustomize sitecustomize = self.site / "sitecustomize.py" @@ -176,11 +134,13 @@ def user_site_packages(self): @user_site_packages.setter def user_site_packages(self, value): self._user_site_packages = value - if self._venv_type == 'virtualenv': - marker = self.lib / "no-global-site-packages.txt" - if self._user_site_packages: - marker.unlink() - else: - marker.touch() - elif self._venv_type == 'venv': - self._customize_site() + self._customize_site() + + pyvenv_cfg = self.location.joinpath("pyvenv.cfg") + modified_lines = [] + for line in pyvenv_cfg.read_text().splitlines(): + k, v = line.split("=", 1) + if k.strip() == "include-system-site-packages": + line = "{}= {}".format(k, "true" if value else "false") + modified_lines.append(line) + pyvenv_cfg.write_text("\n".join(modified_lines)) diff --git a/tools/requirements/tests.txt b/tools/requirements/tests.txt index 00a306558b8..c1af8de36fb 100644 --- a/tools/requirements/tests.txt +++ b/tools/requirements/tests.txt @@ -14,6 +14,6 @@ pytest-xdist<1.28.0 pyyaml setuptools>=39.2.0 # Needed for `setuptools.wheel.Wheel` support. scripttest -https://github.com/pypa/virtualenv/archive/legacy.zip#egg=virtualenv +git+https://github.com/pypa/virtualenv.git@master#egg=virtualenv werkzeug==0.16.0 wheel