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 <range>` 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.
This commit is contained in:
teknium1
2026-09-12 08:15:41 -07:00
committed by Teknium
parent 5bdb4742b0
commit f7990661a0
2 changed files with 12 additions and 4 deletions
+9 -3
View File
@@ -692,7 +692,9 @@ check_python() {
# No 3.11, but any interpreter inside requires-python (>=3.11,<3.14) works: reuse it rather # 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 # 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). # 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_FOUND_VERSION="$("$PYTHON_PATH" --version 2>/dev/null)"
PYTHON_VERSION="$PYTHON_PATH" # uv venv --python / UV_PYTHON pin onto this interpreter 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)" log_success "Python found: $PYTHON_FOUND_VERSION (supported; reusing instead of downloading 3.11)"
@@ -1752,8 +1754,12 @@ setup_venv() {
rm -rf venv rm -rf venv
fi fi
# uv creates the venv and pins the Python version in one step # uv creates the venv and pins the Python version in one step. Fail loudly: `set -e` does not
$UV_CMD venv venv --python "$PYTHON_VERSION" # 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 # 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 # user's shell env). uv honours UV_PYTHON over an existing venv for the
@@ -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: 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``.""" """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=( 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 "DOWNLOAD ATTEMPTED" not in result.stdout, result.stdout
assert "Python found: Python 3.13.12" in result.stdout, result.stdout assert "Python found: Python 3.13.12" in result.stdout, result.stdout