Dependencies
Dependency groups and how to change them.
Dependencies are managed with uv and declared in
pyproject.toml:
- Runtime dependencies (
[project] dependencies) are what users install: NumPy andopt_einsum. Keep this list short; every entry is imposed on every downstream project. - Extras (
[project.optional-dependencies]) enable optional features in production:gpu-nvidiaandgpu-rocmadd CuPy. - Dependency groups (
[dependency-groups]) are for development only and are never installed by users:test:pytest, its plugins, andquimbto build reference networks;bench: what the scripts underbenches/import (cyclopts,quimb,scipy);dev: the linters, type checker and hooks, plustestandbench;interactive: Jupyter and plotting for notebooks;docs: what this site's build needs, plustestandinteractive.
Why uv?
- Its lockfile is compact and multi-platform.
- It gives granular control over which index each dependency comes from, which matters with private indexes.
- It is very fast.
Changing dependencies
- Edit
pyproject.toml. - Run
uv sync --all-groupsto update the environment and regenerateuv.lock, and commit both files. Theuv-lockhook fails if they disagree.
Version constraints
Declare the oldest version that works rather than the one you happen to have
installed: a high floor stops users from installing src_method next to anything
that has not caught up yet. Give every direct dependency a floor, including those
in dependency groups.
Floors are tested rather than assumed: the test workflow has a job on the oldest
supported Python that resolves every direct dependency to its lowest allowed
version (UV_RESOLUTION=lowest-direct). To reproduce it locally:
export UV_RESOLUTION=lowest-direct
uv sync --python 3.11 --no-dev --group test
uv run --no-sync pytest -m "not slow"--no-sync matters: a plain uv run would also install the dev group, at its
lowest versions. Do not commit the uv.lock this produces. Raise a floor only
when the code needs a newer feature or the lowest-resolution job fails.
Tool pins
ruff and ty are pinned twice, in the dev group and in prek.toml. The
check-tool-pins hook fails if the two disagree; update-ruff.yml and
update-ty.yml bump both pins of their tool together.