Python projects
In a Python project that uses uv, every step has its own pyproject.toml
and uv.lock, because they are tracked files. The lockfile, uv.lock, records the exact version of each
package. The .venv is not tracked, so it does not change when you move. It belongs to the replay copy and
not to your repository, and a move never changes it.
Moves forward with uv run
uv run makes the environment match the lockfile of the step before it runs a command. A just recipe
that calls uv run does the same. If you move to a step that adds a package, run uv run pytest or
just test. uv installs the package first.
Problems with uv run
- A move backwards leaves later packages installed.
uv runadds and updates packages, but it does not remove them. Go back from a step that added a package, and the package stays. Code at the earlier step can import it by mistake and still work, and nobody sees the mistake. - Bare commands do not sync. To sync is to make the environment match the lockfile.
python,pytestand other commands that run straight from.venv/binuse the packages that were last installed. - A plain
uv runwrites the lockfile again when it does not matchpyproject.toml. The new lockfile is an edit to a tracked file, so the next move keeps it on a saved branch.uv run --lockedstops with an error instead.
The exact environment at every step
Run uv sync --locked when you arrive at a step. It installs what the step adds and removes what the step
does not list. It also refuses a lockfile that does not match. With a warm cache, it takes about a second.
Make it the first command of each step in your notes:
## step-05 The model
time: 0:21
$ uv sync --locked
$ just testThe Python of timewalk stays out
timewalk itself runs with uv run, in an environment of its own. The shells that timewalk starts take
that environment off PATH. So python in a shell of the class is the Python of the project, and never
the Python of timewalk. See The terminals.