v0.7.2: check ensurepip, not import venv

Found by running install.sh on a second box, not by rereading it. Debian ships
the venv module but splits ensurepip into python3.N-venv. `python3 -c "import
venv"` therefore SUCCEEDS on a machine where `python3 -m venv` cannot work —
the pre-flight passed and the install died two steps later, after writing a
half-built .venv.

Importing a module says nothing about whether it can do its job. The check is
now `import ensurepip`, it runs before anything touches disk, and the error
names the exact versioned package (python3.13-venv on that box).

The old failure text also offered a two-branch diagnosis that matched neither
the real cause nor Python's own message, which already named the right package.
Guessing on top of a correct error makes it worse. It now says where to look
and gets out of the way.

Fired both ways in a sandbox: with ensurepip the install completes; with a
python stubbed to refuse it, the script dies early, prints the versioned apt
package, and leaves no .venv behind.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-13 02:34:11 +08:00
co-authored by Claude Opus 5
parent c21399bd61
commit b928ac54df
+17 -5
View File
@@ -32,16 +32,28 @@ sys.exit(0 if sys.version_info >= (3, 10) else 1)
PY PY
ok "$(cd / && python3 -V)" ok "$(cd / && python3 -V)"
# `import venv` succeeding proves nothing: Debian ships the venv module but
# splits ensurepip into a separate package, and `python3 -m venv` then dies
# with "ensurepip is not available" only after creating a half-built .venv.
# Ask for ensurepip by name, before anything is written to disk.
if ! (cd / && python3 -c "import ensurepip" 2>/dev/null); then
_pyver="$(cd / && python3 -c 'import sys;print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
die "python3 has the venv module but not ensurepip, so it cannot create a venv.
Debian/Ubuntu split this out. Install it and re-run:
sudo apt install python3.${_pyver#*.}-venv
(or: sudo apt install python3-venv)"
fi
ok "ensurepip present"
# ---------------------------------------------------------------- venv # ---------------------------------------------------------------- venv
say "Virtualenv + package" say "Virtualenv + package"
if [[ ! -x "$VENV/bin/python" ]]; then if [[ ! -x "$VENV/bin/python" ]]; then
# Python's own failure text names the exact missing package. Do not paper over
# it with a guess — say where to look and get out of the way.
(cd / && python3 -m venv "$VENV") || die "could not create a venv at $VENV (cd / && python3 -m venv "$VENV") || die "could not create a venv at $VENV
Two things cause this. Read the traceback above to tell them apart: Python printed the reason above; it is more specific than anything this
- 'No module named venv' -> the venv module is not installed. script could infer. A leftover half-built $VENV may need removing first."
Debian/Ubuntu: sudo apt install python3-venv
- anything else -> report it; the installer already runs python
from / to keep this repo off sys.path."
ok "created $VENV" ok "created $VENV"
else else
ok "reusing $VENV" ok "reusing $VENV"