uv-matrix
A simple matrix task runner for Python projects using Astral uv.
Documentation: https://uv-matrix.readthedocs.io/
uv-matrix runs the same project tasks across Python versions, dependency variants, extras, dependency groups, and arbitrary task variants defined in pyproject.toml:
[tool.uv-matrix.matrix.test] # a matrix named "test"
python-version = ["3.12", "3.13"] # run the job on Python 3.12 and 3.13
tasks = ["run_test"] # run the "run_test" task in every cell
[tool.uv-matrix.tasks.run_test] # a task named "run_test"
run = "pytest" # command run through `uv run`
Why uv-matrix?
Many Python projects need to run checks like this:
- run tests against multiple Python versions
- run tests with different optional dependencies
- run lint, docs, and test tasks from one project configuration
- pass the same matrix setup to local development and CI
Installation
uv-matrix requires Python 3.10+ and a working uv installation.
Run it directly:
uvx uv-matrix --help
Or add it to a project:
uv add --dev uv-matrix
uv run uv-matrix --help
Matrices
In this matrix, python-version and webui are axes.
[tool.uv-matrix.matrix.test]
python-version = ["3.12", "3.13"] # reserved axis -> uv run --python
webui = ["django", "flask"] # a custom axis (any name)
tasks = ["test"] # 2 x 2 = 4 jobs
Axes are combined as a cartesian product. In the example above, python-version has 2 values and webui has 2 values, so the test matrix creates 4 jobs.
python-version is a reserved axis. It is inherited by tasks that do not set their own Python version and is passed to uv run --python.
Tasks
Tasks are reusable command definitions.
[tool.uv-matrix.tasks.run_test]
run = "pytest {{ posargs }}" # {{ posargs }}: args after `--`
extras = ["{{ webui }}"] # include the current webui extra. ignored if webui is blank.
when = "sys.platform != 'win32'" # skip this task on Windows
Common task fields include:
run: command to executeextras: optional project extras to includegroups: dependency groups to includecwd: working directory for the commandwhen: condition that decides whether the job should run
The full set of task fields is run, groups, extras, uv-args, env, envfile, cwd, when, python-version, and continue-on-error. An unknown key in a task table (or at the top level of [tool.uv-matrix]) is an error, so a typo such as group for groups fails immediately instead of silently running the job without the intended settings.
Task fields can use Jinja2 templates such as {{ webui }} and {{ posargs }}.
{{ posargs }} expands to arguments passed after --:
uv-matrix run --task run_test -- -k slow
Conditions
when specifies a Python expression. If it evaluates to False, the task is skipped.
Templates and when expressions are evaluated only when running jobs. Commands that only enumerate jobs, such as list, expand the matrix without rendering templates or evaluating when.
Usage
uv-matrix run # run every job from every matrix
uv-matrix run --matrix test # run one matrix
uv-matrix run --filter webui=django # select jobs by axis value
uv-matrix run --task lint # run one task wherever it appears
uv-matrix run --max-jobs 4 # run up to 4 jobs at once
uv-matrix run --dry-run # print commands without running them
uv-matrix run --task run_test -- -k slow # pass extra args as {{ posargs }}
uv-matrix list # list selectable jobs
uv-matrix list --matrix test # list only one matrix's jobs
By default, uv-matrix finds pyproject.toml by walking up from the current directory, then runs from the project root.
Use --config PATH to point to a specific config file, or --project DIR to set the project directory.
How it relates to tox
tox is a mature test environment manager.
uv-matrix is intentionally smaller. It delegates interpreter discovery, environment creation, and dependency resolution to uv, then focuses on one job: expanding matrix definitions into commands.
Instead of encoding combinations into environment names, uv-matrix keeps matrix axes explicit in pyproject.toml.
License
MIT License. See LICENSE for details.
Status
Early development.
Metadata
Release files for uv-matrix 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| uv_matrix-0.0.6.tar.gz | 21.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| uv_matrix-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.5 kB
Release files / uv_matrix-0.0.6.tar.gz
| Download URL | uv_matrix-0.0.6.tar.gz |
|---|---|
| Size | 21.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d67c70fec8ed5050a4e4a0a50de6570f15a7aec81a12e92ae8958ef960bf512e
|
|
BLAKE2b-256 checksum How to use checksums |
dccd948dd0fdb7b82afba3239da1c5499ea37ea988d85dc94259c893e09c6548
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 1, 2026.
Transparency logRelease files / uv_matrix-0.0.6-py3-none-any.whl
| Download URL | uv_matrix-0.0.6-py3-none-any.whl |
|---|---|
| Size | 24.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ee512418598511ca2e3c69cdc2d742e2f90ba422001a9257bc150fba1458884c
|
|
BLAKE2b-256 checksum How to use checksums |
115d34ef798b4fe044350056cc9b549d6c27487704d58c50ba9ee273d8cd1416
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 1, 2026.
Transparency log