def virtualenv_template(request, tmpdir_factory, pip_src, setuptools_install, common_wheels): if six.PY3 and request.config.getoption('--use-venv'): venv_type = 'venv' else: venv_type = 'virtualenv' # Create the virtual environment tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) venv = VirtualEnvironment(tmpdir.join("venv_orig"), venv_type=venv_type) # Install setuptools and pip. install_egg_link(venv, 'setuptools', setuptools_install) pip_editable = Path(str(tmpdir_factory.mktemp('pip'))) / 'pip' pip_src.copytree(pip_editable) assert compileall.compile_dir(str(pip_editable), quiet=1) subprocess.check_call([venv.bin / 'python', 'setup.py', '-q', 'develop'], cwd=pip_editable) # Drop (non-relocatable) launchers. for exe in os.listdir(venv.bin): if not (exe.startswith('python') or exe.startswith('libpy') # Don't remove libpypy-c.so... ): (venv.bin / exe).remove() # Enable user site packages. venv.user_site_packages = True # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" venv.move(venv_template) yield venv
def test_command_line_append_flags(script: PipTestEnvironment, virtualenv: VirtualEnvironment, data: TestData) -> None: """ Test command line flags that append to defaults set by environmental variables. """ script.environ["PIP_FIND_LINKS"] = "https://test.pypi.org" result = script.pip( "install", "-vvv", "INITools", "--trusted-host", "test.pypi.org", ) assert ("Fetching project page and analyzing links: https://test.pypi.org" in result.stdout), str(result) virtualenv.clear() result = script.pip( "install", "-vvv", "--find-links", data.find_links, "INITools", "--trusted-host", "test.pypi.org", ) assert ("Fetching project page and analyzing links: https://test.pypi.org" in result.stdout) assert (f"Skipping link: not a file: {data.find_links}" in result.stdout), f"stdout: {result.stdout}"
def test_env_vars_override_config_file(script: PipTestEnvironment, virtualenv: VirtualEnvironment) -> None: """ Test that environmental variables override settings in config files. """ config_file = script.scratch_path / "test-pip.cfg" # set this to make pip load it script.environ["PIP_CONFIG_FILE"] = str(config_file) # It's important that we test this particular config value ('no-index') # because there is/was a bug which only shows up in cases in which # 'config-item' and 'config_item' hash to the same value modulo the size # of the config dictionary. config_file.write_text( textwrap.dedent("""\ [global] no-index = 1 """)) result = script.pip("install", "-vvv", "INITools", expect_error=True) msg = "DistributionNotFound: No matching distribution found for INITools" # Case insensitive as the new resolver canonicalizes the project name assert msg.lower() in result.stdout.lower(), str(result) script.environ["PIP_NO_INDEX"] = "0" virtualenv.clear() result = script.pip("install", "-vvv", "INITools") assert "Successfully installed INITools" in result.stdout
def test_config_file_override_stack( script: PipTestEnvironment, virtualenv: VirtualEnvironment, mock_server: MockServer, shared_data: TestData, ) -> None: """ Test config files (global, overriding a global config with a local, overriding all with a command line flag). """ mock_server.set_responses([ package_page({}), package_page({}), package_page({"INITools-0.2.tar.gz": "/files/INITools-0.2.tar.gz"}), file_response(shared_data.packages.joinpath("INITools-0.2.tar.gz")), ]) mock_server.start() base_address = f"http://{mock_server.host}:{mock_server.port}" config_file = script.scratch_path / "test-pip.cfg" # set this to make pip load it script.environ["PIP_CONFIG_FILE"] = str(config_file) config_file.write_text( textwrap.dedent("""\ [global] index-url = {}/simple1 """.format(base_address))) script.pip("install", "-vvv", "INITools", expect_error=True) virtualenv.clear() config_file.write_text( textwrap.dedent("""\ [global] index-url = {address}/simple1 [install] index-url = {address}/simple2 """.format(address=base_address))) script.pip("install", "-vvv", "INITools", expect_error=True) script.pip( "install", "-vvv", "--index-url", f"{base_address}/simple3", "INITools", ) mock_server.stop() requests = mock_server.get_requests() assert len(requests) == 4 assert requests[0]["PATH_INFO"] == "/simple1/initools/" assert requests[1]["PATH_INFO"] == "/simple2/initools/" assert requests[2]["PATH_INFO"] == "/simple3/initools/" assert requests[3]["PATH_INFO"] == "/files/INITools-0.2.tar.gz"
def virtualenv_template( request: pytest.FixtureRequest, tmpdir_factory: pytest.TempPathFactory, pip_src: Path, setuptools_install: Path, coverage_install: Path, ) -> Iterator[VirtualEnvironment]: venv_type: VirtualEnvironmentType if request.config.getoption("--use-venv"): venv_type = "venv" else: venv_type = "virtualenv" # Create the virtual environment tmpdir = tmpdir_factory.mktemp("virtualenv") venv = VirtualEnvironment(tmpdir.joinpath("venv_orig"), venv_type=venv_type) # Install setuptools and pip. install_pth_link(venv, "setuptools", setuptools_install) pip_editable = tmpdir_factory.mktemp("pip") / "pip" shutil.copytree(pip_src, pip_editable, symlinks=True) # noxfile.py is Python 3 only assert compileall.compile_dir( str(pip_editable), quiet=1, rx=re.compile("noxfile.py$"), ) subprocess.check_call( [os.fspath(venv.bin / "python"), "setup.py", "-q", "develop"], cwd=pip_editable ) # Install coverage and pth file for executing it in any spawned processes # in this virtual environment. install_pth_link(venv, "coverage", coverage_install) # zz prefix ensures the file is after easy-install.pth. with open(venv.site / "zz-coverage-helper.pth", "a") as f: f.write("import coverage; coverage.process_startup()") # Drop (non-relocatable) launchers. for exe in os.listdir(venv.bin): if not ( exe.startswith("python") or exe.startswith("libpy") # Don't remove libpypy-c.so... ): (venv.bin / exe).unlink() # Enable user site packages. venv.user_site_packages = True # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" venv.move(venv_template) yield venv
def virtualenv_template(request, tmpdir_factory, pip_src, setuptools_install, coverage_install): if six.PY3 and request.config.getoption('--use-venv'): venv_type = 'venv' else: venv_type = 'virtualenv' # Create the virtual environment tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) venv = VirtualEnvironment(tmpdir.joinpath("venv_orig"), venv_type=venv_type) # Install setuptools and pip. install_egg_link(venv, 'setuptools', setuptools_install) pip_editable = Path(str(tmpdir_factory.mktemp('pip'))) / 'pip' shutil.copytree(pip_src, pip_editable, symlinks=True) # noxfile.py is Python 3 only assert compileall.compile_dir( str(pip_editable), quiet=1, rx=re.compile("noxfile.py$"), ) subprocess.check_call([venv.bin / 'python', 'setup.py', '-q', 'develop'], cwd=pip_editable) # Install coverage and pth file for executing it in any spawned processes # in this virtual environment. install_egg_link(venv, 'coverage', coverage_install) # zz prefix ensures the file is after easy-install.pth. with open(venv.site / 'zz-coverage-helper.pth', 'a') as f: f.write('import coverage; coverage.process_startup()') # Drop (non-relocatable) launchers. for exe in os.listdir(venv.bin): if not (exe.startswith('python') or exe.startswith('libpy') # Don't remove libpypy-c.so... ): (venv.bin / exe).unlink() # Enable user site packages. venv.user_site_packages = True # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" venv.move(venv_template) yield venv
def virtualenv(tmpdir, monkeypatch): """ Return a virtual environment which is unique to each test function invocation created inside of a sub directory of the test function's temporary directory. The returned object is a ``tests.lib.venv.VirtualEnvironment`` object. """ # Force shutil to use the older method of rmtree that didn't use the fd # functions. These seem to fail on Travis (and only on Travis). monkeypatch.setattr(shutil, "_use_fd_functions", False, raising=False) # Copy over our source tree so that each virtual environment is self # contained pip_src = tmpdir.join("pip_src").abspath shutil.copytree( SRC_DIR, pip_src, ignore=shutil.ignore_patterns( "*.pyc", "tests", "pip.egg-info", "build", "dist", ".tox", ), ) # Create the virtual environment venv = VirtualEnvironment.create( tmpdir.join("workspace", "venv"), pip_source_dir=pip_src, ) # Undo our monkeypatching of shutil monkeypatch.undo() return venv
def virtualenv_template(tmpdir_factory): tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) # Copy over our source tree so that each virtual environment is self # contained pip_src = tmpdir.join("pip_src").abspath shutil.copytree( SRC_DIR, pip_src, ignore=shutil.ignore_patterns( "*.pyc", "__pycache__", "contrib", "docs", "tasks", "*.txt", "tests", "pip.egg-info", "build", "dist", ".tox", ".git", ), ) # Create the virtual environment venv = VirtualEnvironment.create( tmpdir.join("venv_orig"), pip_source_dir=pip_src, relocatable=True, ) if sys.platform == 'win32': # Work around setuptools' easy_install.exe # not working properly after relocation. for exe in os.listdir(venv.bin): if exe.startswith('easy_install'): (venv.bin / exe).remove() with open(venv.bin / 'easy_install.bat', 'w') as fp: fp.write('python.exe -m easy_install %*\n') # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" os.rename(venv.location, venv_template) yield venv_template tmpdir.rmtree(noerrors=True)
def virtualenv_template(tmpdir_factory): tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) # Copy over our source tree so that each virtual environment is self # contained pip_src = tmpdir.join("pip_src").abspath shutil.copytree( SRC_DIR, pip_src, ignore=shutil.ignore_patterns( "*.pyc", "__pycache__", "contrib", "docs", "tasks", "*.txt", "tests", "pip.egg-info", "build", "dist", ".tox", ".git", ), ) # Create the virtual environment venv = VirtualEnvironment.create( tmpdir.join("venv_orig"), pip_source_dir=pip_src, relocatable=True, ) # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" os.rename(venv.location, venv_template) yield venv_template tmpdir.rmtree(noerrors=True)
def virtualenv(virtualenv_template, tmpdir, isolate): """ Return a virtual environment which is unique to each test function invocation created inside of a sub directory of the test function's temporary directory. The returned object is a ``tests.lib.venv.VirtualEnvironment`` object. """ venv_location = tmpdir.join("workspace", "venv") yield VirtualEnvironment(venv_location, virtualenv_template)
def virtualenv_template(tmpdir_factory, pip_src): tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) # Create the virtual environment venv = VirtualEnvironment.create( tmpdir.join("venv_orig"), pip_source_dir=pip_src, relocatable=True, ) # Fix `site.py`. site_py = venv.lib / 'site.py' with open(site_py) as fp: site_contents = fp.read() for pattern, replace in ( ( # Ensure `virtualenv.system_site_packages = True` (needed # for testing `--user`) 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 site. ( '\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) if sys.platform == 'win32': # Work around setuptools' easy_install.exe # not working properly after relocation. for exe in os.listdir(venv.bin): if exe.startswith('easy_install'): (venv.bin / exe).remove() with open(venv.bin / 'easy_install.bat', 'w') as fp: fp.write('python.exe -m easy_install %*\n') # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" os.rename(venv.location, venv_template) yield venv_template tmpdir.rmtree(noerrors=True)
def test_command_line_options_override_env_vars( script: PipTestEnvironment, virtualenv: VirtualEnvironment) -> None: """ Test that command line options override environmental variables. """ script.environ["PIP_INDEX_URL"] = "https://example.com/simple/" result = script.pip("install", "-vvv", "INITools", expect_error=True) assert "Getting page https://example.com/simple/initools" in result.stdout virtualenv.clear() result = script.pip( "install", "-vvv", "--index-url", "https://download.zope.org/ppix", "INITools", expect_error=True, ) assert "example.com" not in result.stdout assert "Getting page https://download.zope.org/ppix" in result.stdout
def virtualenv(virtualenv_template, tmpdir, isolate): """ Return a virtual environment which is unique to each test function invocation created inside of a sub directory of the test function's temporary directory. The returned object is a ``tests.lib.venv.VirtualEnvironment`` object. """ venv_location = tmpdir.join("workspace", "venv") shutil.copytree(virtualenv_template, venv_location, symlinks=True) venv = VirtualEnvironment(venv_location) yield venv venv_location.rmtree(noerrors=True)
def patch_dist_in_site_packages(virtualenv: VirtualEnvironment) -> None: # Since the tests are run from a virtualenv, and to avoid the "Will not # install to the usersite because it will lack sys.path precedence..." # error: Monkey patch `pip._internal.utils.misc.dist_in_site_packages` # so it's possible to install a conflicting distribution in the user site. virtualenv.sitecustomize = textwrap.dedent(""" def dist_in_site_packages(dist): return False from pip._internal.metadata.base import BaseDistribution BaseDistribution.in_site_packages = property(dist_in_site_packages) """)
def virtualenv_template(request, tmpdir_factory, pip_src, setuptools_install, common_wheels): if six.PY3 and request.config.getoption('--use-venv'): venv_type = 'venv' else: venv_type = 'virtualenv' # Create the virtual environment tmpdir = Path(str(tmpdir_factory.mktemp('virtualenv'))) venv = VirtualEnvironment(tmpdir.join("venv_orig"), venv_type=venv_type) # Install setuptools and pip. install_egg_link(venv, 'setuptools', setuptools_install) pip_editable = Path(str(tmpdir_factory.mktemp('pip'))) / 'pip' pip_src.copytree(pip_editable) assert compileall.compile_dir(str(pip_editable), quiet=1) subprocess.check_call([venv.bin / 'python', 'setup.py', '-q', 'develop'], cwd=pip_editable) # Drop (non-relocatable) launchers. for exe in os.listdir(venv.bin): if not ( exe.startswith('python') or exe.startswith('libpy') # Don't remove libpypy-c.so... ): (venv.bin / exe).remove() # Enable user site packages. venv.user_site_packages = True # Rename original virtualenv directory to make sure # it's not reused by mistake from one of the copies. venv_template = tmpdir / "venv_template" venv.move(venv_template) yield venv
def test_install_user_venv_nositepkgs_fails( self, virtualenv: VirtualEnvironment, script: PipTestEnvironment, data: TestData ) -> None: """ user install in virtualenv (with no system packages) fails with message """ # We can't use PYTHONNOUSERSITE, as it's not # honoured by virtualenv's custom site.py. virtualenv.user_site_packages = False run_from = data.packages.joinpath("FSPkg") result = script.pip( "install", "--user", curdir, cwd=run_from, expect_error=True, ) assert ( "Can not perform a '--user' install. User site-packages are not " "visible in this virtualenv." in result.stderr )
def factory(tmpdir): return VirtualEnvironment(tmpdir, virtualenv_template)
def factory(tmpdir: Path) -> VirtualEnvironment: return VirtualEnvironment(tmpdir, virtualenv_template)