CRUMB a card from devarno-cloud

eva venv Self-Bootstrap Re-exec

eva beginner 3 min read

ELI5

bin/eva checks which kitchen it’s in. If it sees the project’s own kitchen (.venv) on the floor but it’s currently cooking somewhere else, it teleports itself into the project kitchen and starts over. If there’s no project kitchen, it tries to use whatever utensils are nearby and tells you what’s missing.

Technical Deep Dive

Sequence

sequenceDiagram
participant Sh as shell
participant Py1 as system python3
participant Eva as bin/eva
participant Py2 as .venv/bin/python3
Sh->>Py1: exec bin/eva …args
Py1->>Eva: __main__
Eva->>Eva: _VENV_PY = <root>/.venv/bin/python3
alt _VENV_PY exists AND sys.prefix != .venv
Eva->>Py2: os.execv(_VENV_PY, [_VENV_PY, __file__, *argv[1:]])
Py2->>Eva: re-enter __main__ inside venv
else already in venv (sys.prefix == .venv)
Eva->>Eva: continue without re-exec
end
Eva->>Eva: import ruamel.yaml
alt import fails
Eva-->>Sh: stderr "ruamel.yaml not installed - pip install -r requirements.txt"
Eva->>Sh: exit 2
end

Why sys.prefix, not sys.executable

The comment at bin/eva:18-19 is explicit: pyenv venvs share the binary via symlink, so sys.executable already-resolved would still equal the system python’s real path even when running inside a venv. sys.prefix instead reflects the active environment root (<repo>/.venv), giving a stable equality check against _VENV and avoiding an infinite re-exec loop.

Failure Modes

ConditionBehaviour
.venv does not existre-exec is skipped; eva runs under whichever interpreter the shebang resolved
.venv exists but ruamel.yaml missingimport fails, eva writes a one-shot install hint and exits 2 (bin/eva:32-40)
Already inside .venvre-exec block is bypassed entirely

Key Terms

  • os.execv — replaces the current process image; argv[0] must be the executable path (passed as _VENV_PY).
  • sys.prefix — root of the active Python environment; differs from sys.base_prefix inside a venv.
  • shebangbin/eva declares #!/usr/bin/env python3; the interpreter the shell finds first runs the bootstrap, then the bootstrap optionally relocates.

Q&A

Q: Why does bin/eva compare sys.prefix instead of sys.executable? A: Pyenv-style venvs share the python binary via symlink, so sys.executable resolves to the same real path inside and outside the venv. sys.prefix reflects the active environment root and is the only reliable signal that the re-exec already happened (bin/eva:18-21).

Q: What happens when .venv/bin/python3 is missing? A: The os.path.exists(_VENV_PY) check fails and eva runs under the system interpreter without re-execing. If ruamel.yaml is unavailable there too, the import error path emits the install hint and exits 2.

Q: Which third-party import would fail without the bootstrap? A: ruamel.yaml — used for round-trip YAML editing throughout eva (bin/eva:32-34). The bootstrap exists primarily so users do not have to remember to source .venv/bin/activate.

Examples

Terminal window
$ which python3 ; bin/eva list
/usr/bin/python3
# bin/eva re-execs into ~/code/eva-hq/.venv/bin/python3 transparently

neighbors on the map