Exemplo n.º 1
0
def test_getsitepackages_system_site(tmp_path):
    # Test without --system-site-packages
    session = cli_run([ensure_text(str(tmp_path))])

    system_site_packages = get_expected_system_site_packages(session)

    out = subprocess.check_output(
        [str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
        universal_newlines=True,
    )
    site_packages = ast.literal_eval(out)

    for system_site_package in system_site_packages:
        assert system_site_package not in site_packages

    # Test with --system-site-packages
    session = cli_run([ensure_text(str(tmp_path)), "--system-site-packages"])

    system_site_packages = get_expected_system_site_packages(session)

    out = subprocess.check_output(
        [str(session.creator.exe), "-c", r"import site; print(site.getsitepackages())"],
        universal_newlines=True,
    )
    site_packages = ast.literal_eval(out)

    for system_site_package in system_site_packages:
        assert system_site_package in site_packages
Exemplo n.º 2
0
def test_create_vcs_ignore_exists_override(tmp_path):
    git_ignore = tmp_path / ".gitignore"
    git_ignore.write_text("magic")
    cli_run([
        str(tmp_path), "--without-pip", "--no-vcs-ignore", "--activators", ""
    ])
    assert git_ignore.read_text() == "magic"
def test_populated_read_only_cache_and_symlinked_app_data(
        tmp_path, current_fastest, temp_app_data, monkeypatch):
    dest = tmp_path / "venv"
    cmd = [
        "--seeder",
        "app-data",
        "--creator",
        current_fastest,
        "--symlink-app-data",
        "-vv",
        str(dest),
    ]

    assert cli_run(cmd)
    subprocess.check_call(
        (str(dest.joinpath("bin/python")), "-c", "import pip"))

    cached_py_info._CACHE.clear()  # necessary to re-trigger py info discovery
    safe_delete(dest)

    # should succeed with special flag when read-only
    with read_only_dir(temp_app_data):
        assert cli_run(["--read-only-app-data"] + cmd)
        subprocess.check_call(
            (str(dest.joinpath("bin/python")), "-c", "import pip"))
Exemplo n.º 4
0
def test_failed_to_find_implementation(of_id, mocker):
    mocker.patch("virtualenv.run.plugin.creators.CreatorSelector._OPTIONS",
                 return_value={})
    with pytest.raises(RuntimeError) as context:
        cli_run(["-p", of_id])
    assert repr(context.value).startswith(
        'RuntimeError("No virtualenv implementation for')
Exemplo n.º 5
0
def test_failed_to_find_implementation(of_id, mocker):
    mocker.patch("virtualenv.run.plugin.creators.CreatorSelector._OPTIONS", return_value={})
    with pytest.raises(RuntimeError) as context:
        cli_run(["-p", of_id])
    assert repr(context.value) == repr(
        RuntimeError("No virtualenv implementation for {}".format(PythonInfo.current_system()))
    )
Exemplo n.º 6
0
def test_help(capsys):
    with pytest.raises(SystemExit) as context:
        cli_run(args=["-h", "-vvv"])
    assert context.value.code == 0

    out, err = capsys.readouterr()
    assert not err
    assert out
Exemplo n.º 7
0
def test_failed_to_find_bad_spec():
    of_id = uuid4().hex
    with pytest.raises(RuntimeError) as context:
        cli_run(["-p", of_id])
    msg = repr(
        RuntimeError(
            "failed to find interpreter for Builtin discover of python_spec={!r}"
            .format(of_id)))
    assert repr(context.value) == msg
 def _run(name):
     try:
         cli_run([
             "--seeder", "app-data",
             str(tmp_path / name), "--no-pip", "--no-setuptools"
         ])
     except Exception as exception:  # noqa
         as_str = str(exception)
         exceptions.append(as_str)
Exemplo n.º 9
0
def test_version(capsys):
    with pytest.raises(SystemExit) as context:
        cli_run(args=["--version"])
    assert context.value.code == 0

    out, err = capsys.readouterr()
    extra = out if six.PY2 else err
    content = out if six.PY3 else err
    assert not extra

    assert __version__ in content
Exemplo n.º 10
0
def test_create_clear_resets(tmp_path, creator, clear, caplog):
    caplog.set_level(logging.DEBUG)
    if creator == "venv" and clear is False:
        pytest.skip("venv without clear might fail")
    marker = tmp_path / "magic"
    cmd = [str(tmp_path), "--seeder", "app-data", "--without-pip", "--creator", creator, "-vvv"]
    cli_run(cmd)

    marker.write_text("")  # if we a marker file this should be gone on a clear run, remain otherwise
    assert marker.exists()

    cli_run(cmd + (["--clear"] if clear else []))
    assert marker.exists() is not clear
Exemplo n.º 11
0
def test_base_bootstrap_via_pip_invoke(tmp_path, coverage_env, current_fastest, no):
    bundle_ver = BUNDLE_SUPPORT[PythonInfo.current_system().version_release_str]
    create_cmd = [
        "--seeder",
        "pip",
        str(tmp_path / "env"),
        "--download",
        "--pip",
        bundle_ver["pip"].split("-")[1],
        "--setuptools",
        bundle_ver["setuptools"].split("-")[1],
        "--creator",
        current_fastest,
    ]
    if no:
        create_cmd.append("--no-{}".format(no))
    result = cli_run(create_cmd)
    coverage_env()
    assert result

    site_package = result.creator.purelib
    pip = site_package / "pip"
    setuptools = site_package / "setuptools"
    wheel = site_package / "wheel"
    files_post_first_create = list(site_package.iterdir())

    if no:
        no_file = locals()[no]
        assert no not in files_post_first_create

    for key in ("pip", "setuptools", "wheel"):
        if key == no:
            continue
        assert locals()[key] in files_post_first_create
Exemplo n.º 12
0
def test_base_bootstrap_via_pip_invoke(tmp_path, coverage_env, current_fastest):
    bundle_ver = BUNDLE_SUPPORT[PythonInfo.current_system().version_release_str]
    create_cmd = [
        "--seeder",
        "pip",
        str(tmp_path / "env"),
        "--download",
        "--pip",
        bundle_ver["pip"].split("-")[1],
        "--setuptools",
        bundle_ver["setuptools"].split("-")[1],
        "--creator",
        current_fastest,
    ]
    result = cli_run(create_cmd)
    coverage_env()
    assert result

    site_package = result.creator.purelib
    pip = site_package / "pip"
    setuptools = site_package / "setuptools"
    wheel = site_package / "wheel"

    files_post_first_create = list(site_package.iterdir())
    assert pip in files_post_first_create
    assert setuptools in files_post_first_create
    assert wheel in files_post_first_create
Exemplo n.º 13
0
def test_create_distutils_cfg(creator, tmp_path, monkeypatch):
    cmd = [
        ensure_text(str(tmp_path)),
        "--activators",
        "",
        "--creator",
        creator,
    ]
    result = cli_run(cmd)

    app = Path(__file__).parent / "console_app"
    dest = tmp_path / "console_app"
    shutil.copytree(str(app), str(dest))

    setup_cfg = dest / "setup.cfg"
    conf = dedent(
        """
    [install]
    prefix={}/a
    install_scripts={}/b
    """
    ).format(tmp_path, tmp_path)
    setup_cfg.write_text(setup_cfg.read_text() + conf)

    monkeypatch.chdir(dest)  # distutils will read the setup.cfg from the cwd, so change to that
    install_demo_cmd = [str(result.creator.script("pip")), "install", str(dest), "--no-use-pep517"]
    subprocess.check_call(install_demo_cmd)

    magic = result.creator.script("magic")  # console scripts are created in the right location
    assert magic.exists()

    package_folder = result.creator.platlib / "demo"  # prefix is set to the virtualenv prefix for install
    assert package_folder.exists()
Exemplo n.º 14
0
    def create_venv(build_item, bin_dir, src_dir):
        """
        Create a virtualEnv and install the requirements specified within the source code
        """
        packages_file = build_item["virtualenv"]
        venv_path = os.path.join(bin_dir, "venv")
        pip_bin = os.path.join(venv_path, "bin/pip")
        virtualenv.cli_run([venv_path])

        cmd = [pip_bin, "install", "-r", os.path.join(src_dir, packages_file)]
        cmd = shlex.split(" ".join(cmd))
        install_proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
        _, stderr_data = install_proc.communicate()

        if install_proc.returncode != 0:
            raise IPOLConstructVirtualenvError(stderr_data)
Exemplo n.º 15
0
def test_no_preimport_threading(tmp_path, no_coverage):
    session = cli_run([ensure_text(str(tmp_path))])
    out = subprocess.check_output(
        [str(session.creator.exe), "-c", r"import sys; print('\n'.join(sorted(sys.modules)))"], universal_newlines=True,
    )
    imported = set(out.splitlines())
    assert "threading" not in imported
Exemplo n.º 16
0
def zipapp_test_env(tmp_path_factory):
    base_path = tmp_path_factory.mktemp("zipapp-test")
    session = cli_run(
        ["-v", "--activators", "", "--without-pip",
         str(base_path / "env")])
    yield session.creator.exe
    shutil.rmtree(str(base_path))
Exemplo n.º 17
0
def test_cross_major(cross_python, coverage_env, tmp_path, current_fastest,
                     session_app_data):
    cmd = [
        "-v",
        "-v",
        "-p",
        ensure_text(cross_python.executable),
        ensure_text(str(tmp_path)),
        "--no-setuptools",
        "--no-wheel",
        "--activators",
        "",
        "--creator",
        current_fastest,
    ]
    result = cli_run(cmd)
    pip_scripts = {
        i.name.replace(".exe", "")
        for i in result.creator.script_dir.iterdir()
        if i.name.startswith("pip")
    }
    major, minor = cross_python.version_info[0:2]
    assert pip_scripts == {
        "pip", "pip-{}.{}".format(major, minor), "pip{}".format(major)
    }
    coverage_env()
    env = PythonInfo.from_exe(str(result.creator.exe), session_app_data)
    assert env.version_info.major != CURRENT.version_info.major
Exemplo n.º 18
0
def zipapp_build_env(tmp_path_factory):
    create_env_path = None
    if sys.version_info[0:2] >= (3, 5) and CURRENT.implementation != "PyPy":
        exe = CURRENT.executable  # guaranteed to contain a recent enough pip (tox.ini)
    else:
        create_env_path = tmp_path_factory.mktemp("zipapp-create-env")
        exe, found = None, False
        # prefer CPython as builder as pypy is slow
        for impl in ["cpython", ""]:
            for version in range(8, 4, -1):
                try:
                    # create a virtual environment which is also guaranteed to contain a recent enough pip (bundled)
                    session = cli_run([
                        "-vvv", "-p", "{}3.{}".format(impl, version),
                        "--activators", "",
                        str(create_env_path)
                    ])
                    exe = str(session.creator.exe)
                    found = True
                    break
                except Exception:
                    pass
            if found:
                break
        else:
            raise RuntimeError("could not find a python to build zipapp")
        cmd = [
            str(Path(exe).parent / "pip"), "install", "pip>=19.3",
            "packaging>=20"
        ]
        subprocess.check_call(cmd)
    yield exe
    if create_env_path is not None:
        shutil.rmtree(str(create_env_path))
Exemplo n.º 19
0
def test_zip_importer_can_import_setuptools(tmp_path):
    """We're patching the loaders so might fail on r/o loaders, such as zipimporter on CPython<3.8"""
    result = cli_run([
        str(tmp_path / "venv"), "--activators", "", "--no-pip", "--no-wheel",
        "--copies"
    ])
    zip_path = tmp_path / "site-packages.zip"
    with zipfile.ZipFile(str(zip_path), "w",
                         zipfile.ZIP_DEFLATED) as zip_handler:
        lib = str(result.creator.purelib)
        for root, _, files in os.walk(lib):
            base = root[len(lib):].lstrip(os.pathsep)
            for file in files:
                if not file.startswith("_virtualenv"):
                    zip_handler.write(filename=os.path.join(root, file),
                                      arcname=os.path.join(base, file))
    for folder in result.creator.purelib.iterdir():
        if not folder.name.startswith("_virtualenv"):
            if folder.is_dir():
                shutil.rmtree(str(folder), ignore_errors=True)
            else:
                folder.unlink()
    env = os.environ.copy()
    env[str("PYTHONPATH")] = str(zip_path)
    subprocess.check_call([
        str(result.creator.exe), "-c",
        "from setuptools.dist import Distribution"
    ],
                          env=env)
Exemplo n.º 20
0
def test_py_pyc_missing(tmp_path, mocker, session_app_data, py, pyc):
    """Ensure that creation can succeed if os.pyc exists (even if os.py has been deleted)"""
    previous = Python2.from_stdlib

    def from_stdlib(mappings, name):
        path, to, exists = previous(mappings, name)
        if name.endswith("py"):
            exists = py
        elif name.endswith("pyc"):
            exists = pyc
        return path, to, exists

    mocker.patch.object(Python2, "from_stdlib", side_effect=from_stdlib)

    result = cli_run([
        ensure_text(str(tmp_path)), "--without-pip", "--activators", "", "-vv"
    ])
    py_at = Python2.from_stdlib(Python2.mappings(CURRENT),
                                "os.py")[1](result.creator, Path("os.py"))
    py = pyc is False or py  # if pyc is False we fallback to serve the py, which will exist (as we only mock the check)
    assert py_at.exists() is py

    pyc_at = Python2.from_stdlib(Python2.mappings(CURRENT),
                                 "osc.py")[1](result.creator, Path("os.pyc"))
    assert pyc_at.exists() is pyc
Exemplo n.º 21
0
def test_can_build_c_extensions(creator, tmp_path, coverage_env):
    session = cli_run(
        ["--creator", creator, "--seed", "app-data",
         str(tmp_path), "-vvv"])
    coverage_env()
    cmd = [
        str(session.creator.script("pip")),
        "install",
        "--no-index",
        "--no-deps",
        "--disable-pip-version-check",
        "-vvv",
        str(Path(__file__).parent.resolve() / "greet"),
    ]
    process = Popen(cmd)
    process.communicate()
    assert process.returncode == 0

    process = Popen(
        [str(session.creator.exe), "-c", "import greet; greet.greet('World')"],
        universal_newlines=True,
        stdout=subprocess.PIPE,
    )
    out, _ = process.communicate()
    assert process.returncode == 0
    assert out == "Hello World!\n"
def test_base_bootstrap_link_via_app_data_no(tmp_path, coverage_env,
                                             current_fastest, session_app_data,
                                             pkg):
    create_cmd = [str(tmp_path), "--seeder", "app-data", "--no-{}".format(pkg)]
    result = cli_run(create_cmd)
    assert not (result.creator.purelib / pkg).exists()
    for key in {"pip", "setuptools", "wheel"} - {pkg}:
        assert (result.creator.purelib / key).exists()
Exemplo n.º 23
0
def activation_python(tmp_path_factory, special_char_name, current_fastest):
    dest = os.path.join(six.ensure_text(str(tmp_path_factory.mktemp("activation-tester-env"))), special_char_name)
    session = cli_run(["--without-pip", dest, "--prompt", special_char_name, "--creator", current_fastest, "-vv"])
    pydoc_test = session.creator.purelib / "pydoc_test.py"
    pydoc_test.write_text('"""This is pydoc_test.py"""')
    yield session
    if WIN_CPYTHON_2:  # PY2 windows does not support unicode delete
        shutil.rmtree(dest)
Exemplo n.º 24
0
def test_base_bootstrap_via_pip_invoke(tmp_path, coverage_env, mocker,
                                       current_fastest, no):
    bundle_ver = BUNDLE_SUPPORT[
        PythonInfo.current_system().version_release_str]

    extra_search_dir = tmp_path / "extra"
    extra_search_dir.mkdir()

    original = PipInvoke._execute

    def _execute(cmd, env):
        assert set(cmd[-4:]) == {
            "--find-links",
            str(extra_search_dir),
            str(BUNDLE_FOLDER)
        }
        return original(cmd, env)

    run = mocker.patch.object(PipInvoke, "_execute", side_effect=_execute)

    create_cmd = [
        "--seeder",
        "pip",
        str(tmp_path / "env"),
        "--download",
        "--pip",
        bundle_ver["pip"].split("-")[1],
        "--setuptools",
        bundle_ver["setuptools"].split("-")[1],
        "--creator",
        current_fastest,
        "--extra-search-dir",
        str(extra_search_dir),
    ]
    if no:
        create_cmd.append("--no-{}".format(no))
    result = cli_run(create_cmd)
    coverage_env()

    assert result
    assert run.call_count == 1

    site_package = result.creator.purelib
    pip = site_package / "pip"
    setuptools = site_package / "setuptools"
    wheel = site_package / "wheel"
    files_post_first_create = list(site_package.iterdir())

    if no:
        no_file = locals()[no]
        assert no not in files_post_first_create

    for key in ("pip", "setuptools", "wheel"):
        if key == no:
            continue
        assert locals()[key] in files_post_first_create
def test_base_bootstrap_link_via_app_data_not_writable(tmp_path,
                                                       current_fastest,
                                                       read_only_app_data,
                                                       monkeypatch):
    dest = tmp_path / "venv"
    result = cli_run([
        "--seeder", "app-data", "--creator", current_fastest, "-vv",
        str(dest)
    ])
    assert result
Exemplo n.º 26
0
def old_virtualenv(tmp_path_factory, session_app_data):
    if CURRENT.is_old_virtualenv:
        return CURRENT.executable
    else:
        env_for_old_virtualenv = tmp_path_factory.mktemp(
            "env-for-old-virtualenv")
        result = cli_run([
            "--no-download", "--activators", "",
            str(env_for_old_virtualenv), "--no-periodic-update"
        ])
        # noinspection PyBroadException
        try:
            process = Popen(
                [
                    str(result.creator.script("pip")),
                    "install",
                    "--no-index",
                    "--disable-pip-version-check",
                    str(
                        Path(__file__).resolve().parent /
                        "virtualenv-16.7.9-py2.py3-none-any.whl"),
                    "-v",
                ],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            )
            _, __ = process.communicate()
            assert not process.returncode
        except Exception:
            return RuntimeError("failed to install old virtualenv")
        # noinspection PyBroadException
        try:
            old_virtualenv_at = tmp_path_factory.mktemp("old-virtualenv")
            cmd = [
                str(result.creator.script("virtualenv")),
                str(old_virtualenv_at),
                "--no-pip",
                "--no-setuptools",
                "--no-wheel",
            ]
            process = Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
            _, __ = process.communicate()
            assert not process.returncode
            if result.creator.interpreter.implementation == "PyPy" and IS_WIN:
                # old virtualenv creates pypy paths wrong on windows, so have to hardcode it
                return str(old_virtualenv_at / "bin" / "pypy.exe")
            exe_path = CURRENT.discover_exe(
                session_app_data,
                prefix=str(old_virtualenv_at)).original_executable
            return exe_path
        except Exception as exception:
            return RuntimeError(
                "failed to create old virtualenv {}".format(exception))
Exemplo n.º 27
0
def test_python_path(monkeypatch, tmp_path, python_path_on):
    result = cli_run([ensure_text(str(tmp_path)), "--without-pip", "--activators", ""])
    monkeypatch.chdir(tmp_path)
    case_sensitive = fs_is_case_sensitive()

    def _get_sys_path(flag=None):
        cmd = [str(result.creator.exe)]
        if flag:
            cmd.append(flag)
        cmd.extend(["-c", "import json; import sys; print(json.dumps(sys.path))"])
        return [i if case_sensitive else i.lower() for i in json.loads(subprocess.check_output(cmd))]

    monkeypatch.delenv(str("PYTHONPATH"), raising=False)
    base = _get_sys_path()

    # note the value result.creator.interpreter.system_stdlib cannot be set, as that would disable our custom site.py
    python_paths = [
        str(Path(result.creator.interpreter.prefix)),
        str(Path(result.creator.interpreter.system_stdlib) / "b"),
        str(result.creator.purelib / "a"),
        str(result.creator.purelib),
        str(result.creator.bin_dir),
        str(tmp_path / "base"),
        str(tmp_path / "base_sep") + os.sep,
        "name",
        "name{}".format(os.sep),
        str(tmp_path.parent / (ensure_text(tmp_path.name) + "_suffix")),
        ".",
        "..",
        "",
    ]
    python_path_env = os.pathsep.join(ensure_str(i) for i in python_paths)
    monkeypatch.setenv(str("PYTHONPATH"), python_path_env)

    extra_all = _get_sys_path(None if python_path_on else "-E")
    if python_path_on:
        assert extra_all[0] == ""  # the cwd is always injected at start as ''
        extra_all = extra_all[1:]
        assert base[0] == ""
        base = base[1:]

        assert not (set(base) - set(extra_all))  # all base paths are present
        abs_python_paths = list(OrderedDict((os.path.abspath(ensure_text(i)), None) for i in python_paths).keys())
        abs_python_paths = [i if case_sensitive else i.lower() for i in abs_python_paths]

        extra_as_python_path = extra_all[: len(abs_python_paths)]
        assert abs_python_paths == extra_as_python_path  # python paths are there at the start

        non_python_path = extra_all[len(abs_python_paths) :]
        assert non_python_path == [i for i in base if i not in extra_as_python_path]
    else:
        assert base == extra_all
Exemplo n.º 28
0
def test_create_long_path(current_fastest, tmp_path):
    if sys.platform == "darwin":
        max_shebang_length = 512
    else:
        max_shebang_length = 127
    # filenames can be at most 255 long on macOS, so split to to levels
    count = max_shebang_length - len(str(tmp_path))
    folder = tmp_path / ("a" * (count // 2)) / ("b" * (count // 2)) / "c"
    folder.mkdir(parents=True)

    cmd = [str(folder)]
    result = cli_run(cmd)
    subprocess.check_call([str(result.creator.script("pip")), "--version"])
Exemplo n.º 29
0
def test_debug_bad_virtualenv(tmp_path):
    cmd = [str(tmp_path), "--without-pip"]
    result = cli_run(cmd)
    # if the site.py is removed/altered the debug should fail as no one is around to fix the paths
    site_py = result.creator.stdlib / "site.py"
    site_py.unlink()
    # insert something that writes something on the stdout
    site_py.write_text('import sys; sys.stdout.write(repr("std-out")); sys.stderr.write("std-err"); raise ValueError')
    debug_info = result.creator.debug
    assert debug_info["returncode"]
    assert debug_info["err"].startswith("std-err")
    assert "std-out" in debug_info["out"]
    assert debug_info["exception"]
Exemplo n.º 30
0
def test_prompt_set(tmp_path, creator, prompt):
    cmd = [str(tmp_path), "--seeder", "app-data", "--without-pip", "--creator", creator]
    if prompt is not None:
        cmd.extend(["--prompt", "magic"])

    result = cli_run(cmd)
    actual_prompt = tmp_path.name if prompt is None else prompt
    cfg = PyEnvCfg.from_file(result.creator.pyenv_cfg.path)
    if prompt is None:
        assert "prompt" not in cfg
    else:
        if creator != "venv":
            assert "prompt" in cfg, list(cfg.content.keys())
            assert cfg["prompt"] == actual_prompt