1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
from __future__ import annotations
from pathlib import Path
from unittest.mock import PropertyMock
import pytest
from packaging.version import parse
from findpython.providers import ALL_PROVIDERS, PathProvider
from findpython.python import PythonVersion
class _MockRegistry:
def __init__(self) -> None:
self.versions: dict[Path, PythonVersion] = {}
def add_python(
self,
executable,
version=None,
architecture="64bit",
interpreter=None,
keep_symlink=False,
freethreaded=False,
) -> PythonVersion:
if version is not None:
version = parse(version)
executable = Path(executable)
if interpreter is None:
interpreter = executable
executable.parent.mkdir(parents=True, exist_ok=True)
executable.touch(exist_ok=True)
executable.chmod(0o744)
py_ver = PythonVersion(
executable, version, architecture, interpreter, keep_symlink, freethreaded
)
if version is not None:
py_ver._get_version = lambda: version # type:ignore[method-assign]
self.versions[executable] = py_ver
return py_ver
def version_maker(self, executable, *args, **kwargs) -> PythonVersion:
return self.versions[executable]
@pytest.fixture()
def mocked_python(tmp_path, monkeypatch) -> _MockRegistry:
mocked = _MockRegistry()
for python in [
(tmp_path / "python3.7", "3.7.0"),
(tmp_path / "python3.8", "3.8.0"),
(tmp_path / "python3.9", "3.9.0"),
]:
mocked.add_python(*python)
monkeypatch.setattr(
"findpython.providers.base.BaseProvider.version_maker", mocked.version_maker
)
monkeypatch.setattr(
"findpython.python.PythonVersion.implementation",
PropertyMock(return_value="cpython"),
)
ALL_PROVIDERS.clear()
ALL_PROVIDERS["path"] = PathProvider
monkeypatch.setenv("PATH", str(tmp_path))
return mocked
@pytest.fixture(params=[False, True])
def switch(request) -> bool:
return request.param
|