Moving from Tox to uv

Why switch?

  • An automatically resolved lockfile: our current requirements file mixes exact pins with ranges such as Sphinx>=8.2.0. uv.lock records the full resolved set, so fresh local and CI environments use the same versions.

  • Clearer dependency declarations: pyproject.toml identifies packages we intentionally use. The lockfile records their indirect dependencies, which maintainers would otherwise have to track in the requirements file.

  • Fewer setup steps: uv can install the Python version in .python-version and manage the project environment. Contributors no longer need to install that Python separately or create a Conda environment before installing Tox.

  • Faster cached setup: in two local runs with warm package caches, median fresh-environment setup took about 21 seconds with Tox/pip and 0.09 seconds with uv. Full HTML builds took about 33 seconds with either workflow.

Dependabot continues to manage Python dependency updates. Maintainers review uv.lock alongside changes to pyproject.toml.

Switch your local checkout

  1. Install uv version 0.13.5 or newer.

  2. Stop any running Sphinx preview. Deactivate a Conda or Python virtual environment previously used to build this repository.

  3. Pull the updated repository and initialise its existing submodule:

    git submodule update --init --recursive
    
  4. From the repository root, install the locked dependencies and build:

    uv sync --locked
    uv run --locked sphinx-build -b html -W -d _build/doctrees . _build/html
    

uv creates .venv for this checkout. It does not reuse .tox; you can keep that directory while transitioning. Each worktree has its own environment. You do not need to activate .venv when using uv run.

If you have Make installed, use these shortcuts:

Old and new commands

Previous command

uv workflow

tox -e py313

make html

tox -e py313-livehtml

make serve

tox -e py313-linkcheck

make html linkcheck

pip install -r requirements.txt

uv sync --locked

make serve PORT=8080 selects a different preview port. Press Ctrl+C to stop the preview before running a separate build in the same worktree. The README gives direct uv commands for systems without Make, including Windows.

After pulling dependency changes, run uv sync --locked. Documentation-only edits should leave pyproject.toml and uv.lock unchanged.

--locked tells uv to use the saved dependency versions in uv.lock. If you change dependencies in pyproject.toml without updating uv.lock, the command stops; follow the README’s dependency-update instructions.

For dependency updates, use the README’s maintenance commands and commit the relevant manifest and lockfile changes together. Do not edit uv.lock by hand. Changing Python itself requires updating .python-version, reviewing requires-python in pyproject.toml, refreshing the lockfile and rebuilding.