vpython is a thread- and process-safe python wrapper/launcher script. It exposes a
python-compatible CLI, sets up (or reuses) a virtual environment, installs dependencies
when needed, and then delegates execution to the target Python interpreter.
- Determine the project root by walking up from the current working directory and
looking for common Python project markers (
requirements.txt,pyproject.toml,.git, etc.). - Decide where to store the virtual environment (project-local
.venvor a cache directory). - Acquire a cross-platform file lock so concurrent invocations share the same venv.
- Create the venv if missing and optionally install dependencies.
execinto the venv'spythonwith the original CLI arguments.
The wrapper is intended to be invoked like python:
./python3 -c "print('hello from vpython')"
./python3 -m pip --version
./python3 path/to/script.py --arg valueDependency installation is automatic unless disabled. The mode is determined by
PYWRAP_DEP_MODE or by project files:
requirements(default ifrequirements.txtexists) installs from the file specified byPYWRAP_REQUIREMENTS(default:<project_root>/requirements.txt). It also considers optional constraint/lock files (constraints.txt,constraints.lock,requirements.lock) when computing the dependency hash.pyproject(default whenpyproject.tomlexists) installs the project in editable mode (pip install -e .). It includespoetry.lock,pdm.lock,uv.lock, andPipfile.lockin the dependency hash when present.noneskips dependency installation entirely.
When dependencies (or the base interpreter) change, the wrapper recomputes a hash and
reinstalls as needed, storing metadata in .venv/.pywrap/ok.json.
PYWRAP_BASE_PYTHON: Path to the interpreter used to create the venv (defaults to the currentsys.executable).PYWRAP_VENV_MODE:projectfor<project_root>/.venv(default) orcachefor a shared cache in~/.cache/pywrap.PYWRAP_CACHE_DIR: Override the cache root whenPYWRAP_VENV_MODE=cache.PYWRAP_DEP_MODE:requirements,pyproject, ornone(auto-detected if unset).PYWRAP_REQUIREMENTS: Path to the requirements file (default:<project_root>/requirements.txt).PYWRAP_INSTALL_DEPS: Set to1to install dependencies when the marker hash has changed (defaults to0).PYWRAP_FORCE_RECREATE: Set to1to delete and recreate the venv on every run.PYWRAP_UPGRADE_PIP: Set to0to skip upgradingpip,setuptools, andwheelbefore installs (defaults to1).PYWRAP_LOCAL_FIRST: Set to1to runpip downloadbefore installs and then install from the local download cache viapip install --no-index --find-links.PYWRAP_PIP_ARGS: Extra arguments passed topip(e.g.--index-url,--extra-index-url).PYWRAP_LOCK_TIMEOUT_SEC: Seconds to wait for the venv lock (default:1800).PYWRAP_LOCK_POLL_SEC: Lock polling interval in seconds (default:0.2).PYWRAP_VERBOSE: Set to1for stderr diagnostics.
- Concurrency is guarded by an OS-level file lock (
.venv.lockor cache lock) to keep multiple processes from corrupting the environment. - The wrapper will self-heal a partially-created venv by removing it and recreating.