def test_py_info_cached_symlink(mocker, tmp_path, session_app_data): spy = mocker.spy(cached_py_info, "_run_subprocess") first_result = PythonInfo.from_exe(sys.executable, session_app_data) assert first_result is not None count = spy.call_count # 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) pyvenv = Path(sys.executable).parents[1] / "pyvenv.cfg" if pyvenv.exists(): (tmp_path / pyvenv.name).write_text(pyvenv.read_text()) new_exe_str = str(new_exe) second_result = PythonInfo.from_exe(new_exe_str, session_app_data) assert second_result.executable == new_exe_str assert spy.call_count == count + 1 # no longer needed the host invocation, but the new symlink is must
def test_discover_ok(tmp_path, monkeypatch, suffix, impl, version, arch, into, caplog, session_app_data): caplog.set_level(logging.DEBUG) folder = tmp_path / into folder.mkdir(parents=True, exist_ok=True) dest = folder / "{}{}".format(impl, version, arch, suffix) os.symlink(CURRENT.executable, str(dest)) pyvenv = Path(CURRENT.executable).parents[1] / "pyvenv.cfg" if pyvenv.exists(): (folder / pyvenv.name).write_text(pyvenv.read_text()) inside_folder = str(tmp_path) base = CURRENT.discover_exe(session_app_data, inside_folder) found = base.executable dest_str = str(dest) if not fs_is_case_sensitive(): found = found.lower() dest_str = dest_str.lower() assert found == dest_str assert len(caplog.messages) >= 1, caplog.text assert "get interpreter info via cmd: " in caplog.text dest.rename(dest.parent / (dest.name + "-1")) CURRENT._cache_exe_discovery.clear() with pytest.raises(RuntimeError): CURRENT.discover_exe(session_app_data, inside_folder)