From f7990661a0c41b3fdd0018401597a3aa5c3c9c70 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sat, 12 Sep 2026 08:15:41 -0700 Subject: [PATCH] fix(install): reuse probe skips the active venv; venv creation failure is fatal Review finding: with the install's own venv activated (a re-run), `uv python find ` returned venv/bin/python3, which setup_venv then deleted before handing the dead path to `uv venv`; the stage still exited 0 and printed "Virtual environment ready". Probe with --system so only base interpreters qualify, and fail the stage when the venv was not created. --- scripts/install.sh | 12 +++++++++--- tests/test_install_sh_reuse_supported_python.py | 4 +++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/install.sh b/scripts/install.sh index be4f977e33..1f2635673c 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -692,7 +692,9 @@ check_python() { # No 3.11, but any interpreter inside requires-python (>=3.11,<3.14) works: reuse it rather # than downloading 3.11 — the download is a hard failure on hosts that cannot reach GitHub # releases, and the user already has a supported Python (#10778). - if PYTHON_PATH="$("$UV_CMD" python find "$PYTHON_SUPPORTED_RANGE" 2>/dev/null)"; then + # --system: with the install's own venv activated (a re-run), `uv python find` would return + # venv/bin/python3, which setup_venv is about to delete out from under itself. + if PYTHON_PATH="$("$UV_CMD" python find --system "$PYTHON_SUPPORTED_RANGE" 2>/dev/null)"; then PYTHON_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)" PYTHON_VERSION="$PYTHON_PATH" # uv venv --python / UV_PYTHON pin onto this interpreter log_success "Python found: $PYTHON_FOUND_VERSION (supported; reusing instead of downloading 3.11)" @@ -1752,8 +1754,12 @@ setup_venv() { rm -rf venv fi - # uv creates the venv and pins the Python version in one step - $UV_CMD venv venv --python "$PYTHON_VERSION" + # uv creates the venv and pins the Python version in one step. Fail loudly: `set -e` does not + # reach this line's callers on every path, and a missing venv used to be reported as ready. + if ! $UV_CMD venv venv --python "$PYTHON_VERSION" || [ ! -x "venv/bin/python" ]; then + log_error "Failed to create the virtual environment with Python $PYTHON_VERSION" + exit 1 + fi # Neutralize any inherited UV_PYTHON (e.g. UV_PYTHON=3.14 left in the # user's shell env). uv honours UV_PYTHON over an existing venv for the diff --git a/tests/test_install_sh_reuse_supported_python.py b/tests/test_install_sh_reuse_supported_python.py index 269fb0bf80..82805ec971 100644 --- a/tests/test_install_sh_reuse_supported_python.py +++ b/tests/test_install_sh_reuse_supported_python.py @@ -45,6 +45,8 @@ def _run_prerequisites(tmp_path: Path, *, uv_find_script: str) -> subprocess.Com def test_supported_newer_python_is_reused_instead_of_downloading_311(tmp_path: Path) -> None: """3.11 absent, 3.13 present: the installer must take 3.13 and never call ``uv python install``.""" result = _run_prerequisites(tmp_path, uv_find_script=( - f" [ \"$3\" = 3.11 ] && exit 2\n [ \"$3\" = '>=3.11,<3.14' ] && {{ echo {tmp_path}/bin/python3.13; exit 0; }}\n exit 2\n")) + # The range probe must carry --system: with the install's own venv activated, a plain + # `uv python find` returns venv/bin/python3, which setup_venv then deletes. + f" [ \"$3\" = 3.11 ] && exit 2\n [ \"$3\" = --system ] && [ \"$4\" = '>=3.11,<3.14' ] && {{ echo {tmp_path}/bin/python3.13; exit 0; }}\n exit 2\n")) assert "DOWNLOAD ATTEMPTED" not in result.stdout, result.stdout assert "Python found: Python 3.13.12" in result.stdout, result.stdout