Dry runs 1.3
Every command that changes your environment can show what it would do first. --dry-run prints the plan: each step in order, its exact command line, the files it would create or change, and why, under the solver's reason for the chosen Python. Nothing is executed, written or downloaded.
pypilot setup --dry-run
pypilot install httpx --dry-run
pypilot fix python --dry-run
pypilot fix cuda --dry-run
pypilot doctor --fix --dry-run # the report, then the plan "Fix environment" would run
pypilot setup --dry-run --json # the plan as JSON--dry-run needs engine 1.3.0 or newer; 1.2.2 and older do not have it.
What a plan shows
$ pypilot setup --dry-run
PyPilot setup --dry-run: C:\src\demo (uv mode, Python 3.12)
Python 3.12 chosen: dependencies support 3.12; mediapipe caps the upper bound (supports 3.9–3.12).
• ensure uv: uv 0.13.5 (on PATH)
── Plan (nothing was changed) ───────────────────────────
1. uv init
$ uv init --bare --no-workspace --pin-python --python 3.12
writes: pyproject.toml, .python-version
why: the project has no pyproject.toml; create a bare one pinned to Python 3.12 so `uv add` has a manifest to record dependencies in
2. uv python install 3.12
$ uv python install 3.12
why: make CPython 3.12 available (uv downloads it into its own Python store if missing)
3. uv venv
$ uv venv --clear --python 3.12 C:\src\demo\.venv
writes: .venv
why: create the project environment on Python 3.12, replacing any existing one
4. uv add -r requirements.txt
$ uv add -r requirements.txt
writes: pyproject.toml, uv.lock, .venv
why: move requirements.txt's dependencies into pyproject.toml and install them
Dry run only; run without --dry-run to apply.
- The header names the mode (
uv,uv-pip,piporpixi) and the Python the run would use, then the solver's reason for it. - Lines with
•are the read-only checks the real run makes first (here: is uv onPATH). They run during a dry run too, because the plan depends on them. - Each numbered step is a process the real run would start, with
$and its argument vector,writes:(paths relative to the project) andwhy:. A step that is not a process (writing the PyTorch index intopyproject.toml, downloading uv, the GPU self-test) has no$line. Nothing to do.when the environment already matches, for examplefix cudain a project without torch or tensorflow.
Why you can trust it
The plan is not a separate description of what the command does. The command runs its own code path with every change recorded instead of made: each subprocess, file write and download goes through one executor that, in a dry run, notes the step and returns. So the plan is what the real run does on this machine, today, with these settings. Only the probes and PyPI lookups the analysis always makes actually run.
What it cannot know in advance: the result of a step that never ran. If the real uv add would fail on a resolver conflict, the plan still lists uv add; pypilot doctor and the uv dry-run finding are where such conflicts show up.
When the real run would stop
If the run would stop before it finishes, the plan says where, and the command exits with status 1. Here pip mode needs a Python that is not installed, and pip cannot fetch one:
PyPilot setup --dry-run: C:\src\pipdemo (pip mode, Python 3.12)
Python 3.12 chosen: dependencies support 3.9–3.12; mediapipe caps the upper bound (supports 3.9–3.12).
✗ select interpreter: Python 3.12 is required but not installed. Install it (e.g. from python.org or your package manager), then run setup again. pip mode cannot fetch interpreters.
── Plan (nothing was changed) ───────────────────────────
Nothing to do.
✗ The run would stop here: select interpreter: Python 3.12 is required but not installed. Install it (e.g. from python.org or your package manager), then run setup again. pip mode cannot fetch interpreters.
pypilot setup: the plan stops before it finishes: select interpreter: Python 3.12 is required but not installed. Install it (e.g. from python.org or your package manager), then run setup again. pip mode cannot fetch interpreters.In scripts, the exit status is the quickest check: 0 means the plan runs to the end.
JSON
With --json the plan replaces the command's usual document. command is the command as typed (doctor --fix for that one), dry_run is true, and ok is true exactly when plan.blocked is null:
| Key | Meaning |
|---|---|
plan.mode | A resolved_mode value: uv_full, uv_pip_compat, pure_pip or pixi |
plan.python | The Python the run would use, or null |
plan.why | The solver's reason, as in the text header |
plan.steps | [{ "name", "command": [argv], "writes": [paths], "why" }]. command is the exact argument vector, program first; empty for a step that is not a process. writes holds absolute paths |
plan.notes | The read-only checks: [{ "name", "ok", "detail" }] |
plan.blocked | Why the real run would stop, else null |
pypilot setup --dry-run --json for the project above:
{
"pypilot": "1.3.0",
"command": "setup",
"ok": true,
"dry_run": true,
"plan": {
"mode": "uv_full",
"python": "3.12",
"why": "Python 3.12 chosen: dependencies support 3.12; mediapipe caps the upper bound (supports 3.9–3.12).",
"steps": [
{
"name": "uv init",
"command": [
"uv",
"init",
"--bare",
"--no-workspace",
"--pin-python",
"--python",
"3.12"
],
"writes": [
"C:\\src\\demo\\pyproject.toml",
"C:\\src\\demo\\.python-version"
],
"why": "the project has no pyproject.toml; create a bare one pinned to Python 3.12 so `uv add` has a manifest to record dependencies in"
},
{
"name": "uv python install 3.12",
"command": [
"uv",
"python",
"install",
"3.12"
],
"writes": [],
"why": "make CPython 3.12 available (uv downloads it into its own Python store if missing)"
},
{
"name": "uv venv",
"command": [
"uv",
"venv",
"--clear",
"--python",
"3.12",
"C:\\src\\demo\\.venv"
],
"writes": [
"C:\\src\\demo\\.venv"
],
"why": "create the project environment on Python 3.12, replacing any existing one"
},
{
"name": "uv add -r requirements.txt",
"command": [
"uv",
"add",
"-r",
"requirements.txt"
],
"writes": [
"C:\\src\\demo\\pyproject.toml",
"C:\\src\\demo\\uv.lock",
"C:\\src\\demo\\.venv"
],
"why": "move requirements.txt's dependencies into pyproject.toml and install them"
}
],
"notes": [
{
"name": "ensure uv",
"ok": true,
"detail": "uv 0.13.5 (on PATH)"
}
],
"blocked": null
}
}In the editors
The editors' buttons (Fix environment, quick fixes) run the same code without --dry-run. To see what one of them would do, run the matching command with --dry-run in the project folder: Fix environment is pypilot setup (or pypilot doctor --fix), an install quick fix is pypilot install <package>, and pypilot fix python shows the rebuild onto the recommended Python that a "Rebuild environment on Python X.Y" quick fix starts with.
