diff --git a/nox/virtualenv.py b/nox/virtualenv.py index fea1c9be..aa5f3edf 100644 --- a/nox/virtualenv.py +++ b/nox/virtualenv.py @@ -69,12 +69,18 @@ def find_uv() -> tuple[bool, str]: def uv_version() -> version.Version: - ret = subprocess.run( - [UV, "version", "--output-format", "json"], - check=False, - text=True, - capture_output=True, - ) + """Returns uv's version defaulting to 0.0 if uv is not available""" + try: + ret = subprocess.run( + [UV, "version", "--output-format", "json"], + check=False, + text=True, + capture_output=True, + ) + except FileNotFoundError: + logger.info("uv binary not found.") + return version.Version("0.0") + if ret.returncode == 0 and ret.stdout: return version.Version(json.loads(ret.stdout).get("version")) else: @@ -92,10 +98,9 @@ def uv_install_python(python_version: str) -> bool: HAS_UV, UV = find_uv() -if HAS_UV: - # supported since uv 0.3 but 0.4.16 is the first version that doesn't cause - # issues for nox with pypy/cpython confusion - UV_PYTHON_SUPPORT = uv_version() >= version.Version("0.4.16") +# supported since uv 0.3 but 0.4.16 is the first version that doesn't cause +# issues for nox with pypy/cpython confusion +UV_PYTHON_SUPPORT = uv_version() >= version.Version("0.4.16") class InterpreterNotFound(OSError): diff --git a/tests/test_virtualenv.py b/tests/test_virtualenv.py index 534ebf41..962f3e93 100644 --- a/tests/test_virtualenv.py +++ b/tests/test_virtualenv.py @@ -633,7 +633,7 @@ def find_uv_bin(): (1, '{"version": "9.9.9", "commit_info": null}', "0.0"), ], ) -def test_uv_version_error(monkeypatch, return_code, stdout, expected_result): +def test_uv_version(monkeypatch, return_code, stdout, expected_result): def mock_run(*args, **kwargs): return subprocess.CompletedProcess( args=["uv", "version", "--output-format", "json"], @@ -645,6 +645,14 @@ def mock_run(*args, **kwargs): assert nox.virtualenv.uv_version() == version.Version(expected_result) +def test_uv_version_no_uv(monkeypatch): + def mock_exception(*args, **kwargs): + raise FileNotFoundError + + monkeypatch.setattr(subprocess, "run", mock_exception) + assert nox.virtualenv.uv_version() == version.Version("0.0") + + @pytest.mark.parametrize( ["requested_python", "expected_result"], [