diff --git a/.dockerignore b/.dockerignore index 172bf57..2fe44d6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,4 @@ .tox +pip-wheel-metadata +venv* +*.pyz diff --git a/.gitignore b/.gitignore index 383cce2..76055e6 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,5 @@ venv* *wheel-store* -Dockerfile +Dockerfile* .dockerignore diff --git a/docs/changelog/1721.bugfix.rst b/docs/changelog/1721.bugfix.rst new file mode 100644 index 0000000..52acd48 --- /dev/null +++ b/docs/changelog/1721.bugfix.rst @@ -0,0 +1,2 @@ +Allow the test suite to pass even when called with the system Python - to help repackaging of the tool for Linux +distributions - by :user:`gaborbernat`. diff --git a/tests/unit/create/test_creator.py b/tests/unit/create/test_creator.py index e3a3915..1153fda 100644 --- a/tests/unit/create/test_creator.py +++ b/tests/unit/create/test_creator.py @@ -61,6 +61,10 @@ def test_destination_exists_file(tmp_path, capsys): @pytest.mark.skipif(sys.platform == "win32", reason="Windows only applies R/O to files") def test_destination_not_write_able(tmp_path, capsys): + if hasattr(os, "geteuid"): + if os.geteuid() == 0: + pytest.skip("no way to check permission restriction when running under root") + target = tmp_path prev_mod = target.stat().st_mode target.chmod(S_IREAD | S_IRGRP | S_IROTH) @@ -196,8 +200,8 @@ def test_create_no_seed(python, creator, isolated, system, coverage_env, special exes = ("python.exe",) else: exes = ("python", "python{}".format(*sys.version_info), "python{}.{}".format(*sys.version_info)) - # pypy3<=7.3: https://bitbucket.org/pypy/pypy/pull-requests/697 - if IS_PYPY and creator_key == "venv": + if creator_key == "venv": + # for venv some repackaging does not includes the pythonx.y exes = exes[:-1] for exe in exes: exe_path = result.creator.bin_dir / exe @@ -218,6 +222,10 @@ def test_create_no_seed(python, creator, isolated, system, coverage_env, special @pytest.mark.skipif(not CURRENT.has_venv, reason="requires interpreter with venv") def test_venv_fails_not_inline(tmp_path, capsys, mocker): + if hasattr(os, "geteuid"): + if os.geteuid() == 0: + pytest.skip("no way to check permission restriction when running under root") + def _session_via_cli(args, options=None): session = session_via_cli(args, options) assert session.creator.can_be_inline is False @@ -396,14 +404,33 @@ def test_create_distutils_cfg(creator, tmp_path, monkeypatch): 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"] + install_demo_cmd = [ + str(result.creator.script("pip")), + "--disable-pip-version-check", + "install", + str(dest), + "--no-use-pep517", + "-vv", + ] 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() + package_folder = result.creator.purelib / "demo" # prefix is set to the virtualenv prefix for install + assert package_folder.exists(), list_files(str(tmp_path)) + + +def list_files(path): + result = "" + for root, _, files in os.walk(path): + level = root.replace(path, "").count(os.sep) + indent = " " * 4 * level + result += "{}{}/\n".format(indent, os.path.basename(root)) + sub = " " * 4 * (level + 1) + for f in files: + result += "{}{}\n".format(sub, f) + return result @pytest.mark.parametrize("python_path_on", [True, False], ids=["on", "off"]) diff --git a/tests/unit/create/test_interpreters.py b/tests/unit/create/test_interpreters.py index 002326b..cee3cfa 100644 --- a/tests/unit/create/test_interpreters.py +++ b/tests/unit/create/test_interpreters.py @@ -18,7 +18,12 @@ def test_failed_to_find_bad_spec(): assert repr(context.value) == msg -@pytest.mark.parametrize("of_id", [sys.executable, PythonInfo.current_system().implementation]) +SYSTEM = PythonInfo.current_system() + + +@pytest.mark.parametrize( + "of_id", ({sys.executable} if sys.executable != SYSTEM.executable else set()) | {SYSTEM.implementation} +) 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: diff --git a/tests/unit/discovery/py_info/test_py_info.py b/tests/unit/discovery/py_info/test_py_info.py index e673fcd..04001cb 100644 --- a/tests/unit/discovery/py_info/test_py_info.py +++ b/tests/unit/discovery/py_info/test_py_info.py @@ -133,11 +133,13 @@ def test_py_info_cached_symlink_error(mocker, tmp_path, session_app_data): def test_py_info_cache_clear(mocker, tmp_path, session_app_data): spy = mocker.spy(cached_py_info, "_run_subprocess") - assert PythonInfo.from_exe(sys.executable, session_app_data) is not None - assert spy.call_count >= 2 # at least two, one for the venv, one more for the host + result = PythonInfo.from_exe(sys.executable, session_app_data) + assert result is not None + count = 1 if result.executable == sys.executable else 2 # at least two, one for the venv, one more for the host + assert spy.call_count >= count PythonInfo.clear_cache(session_app_data) assert PythonInfo.from_exe(sys.executable, session_app_data) is not None - assert spy.call_count >= 4 + assert spy.call_count >= 2 * count @pytest.mark.skipif(not fs_supports_symlink(), reason="symlink is not supported") @@ -146,7 +148,9 @@ def test_py_info_cached_symlink(mocker, tmp_path, session_app_data): first_result = PythonInfo.from_exe(sys.executable, session_app_data) assert first_result is not None count = spy.call_count - assert count >= 2 # at least two, one for the venv, one more for the host + # at least two, one for the venv, one more for the host + exp_count = 1 if first_result.executable == sys.executable else 2 + assert count >= exp_count # at least two, one for the venv, one more for the host new_exe = tmp_path / "a" new_exe.symlink_to(sys.executable) diff --git a/tests/unit/discovery/test_discovery.py b/tests/unit/discovery/test_discovery.py index 275623a..2533875 100644 --- a/tests/unit/discovery/test_discovery.py +++ b/tests/unit/discovery/test_discovery.py @@ -16,7 +16,7 @@ from virtualenv.util.six import ensure_text @pytest.mark.skipif(not fs_supports_symlink(), reason="symlink not supported") @pytest.mark.parametrize("case", ["mixed", "lower", "upper"]) -def test_discovery_via_path(monkeypatch, case, special_name_dir, caplog, session_app_data): +def test_discovery_via_path(monkeypatch, case, tmp_path, caplog, session_app_data): caplog.set_level(logging.DEBUG) current = PythonInfo.current_system(session_app_data) core = "somethingVeryCryptic{}".format(".".join(str(i) for i in current.version_info[0:3])) @@ -26,7 +26,7 @@ def test_discovery_via_path(monkeypatch, case, special_name_dir, caplog, session elif case == "upper": name = name.upper() exe_name = "{}{}{}".format(name, current.version_info.major, ".exe" if sys.platform == "win32" else "") - target = special_name_dir / current.distutils_install["scripts"] + target = tmp_path / current.distutils_install["scripts"] target.mkdir(parents=True) executable = target / exe_name os.symlink(sys.executable, ensure_text(str(executable)))