A quick uv
recipe I figured out today, for running the tests for a project against multiple Python versions.
The key command option is uv run --with-editable .[test]
.
Start with any Python project that has a [test]
extra defined, for example:
cd /tmp
git clone https://github.com/simonw/datasette
cd datasette
Then run uv
against it with a specific Python version like this:
uv run --python 3.14 --isolated --with-editable '.[test]' pytest -n auto
Here I'm using --isolated
to make sure nothing from any other environments sneaks in.
The --with-editable '.[test]'
part is important - it tells uv
to install the current project in editable mode so that changes you make will be picked up. I first tried this using --with '.[test]'
and was confused as to why changes I made to the code weren't being picked up when I re-ran the tests.
Datasette uses pytest-xdist
to run tests in parallel, so I added -n auto
to have it automatically use all available CPU cores.
I wrote a little helper script (with ChatGPT's help) to make this easier to remember. It uses Python 3.14 by default but you can pass a different version as the -p
argument. Any subsequent arguments will be passed to pytest
.
#!/bin/sh
set -eu # (no pipefail in POSIX sh)
usage() {
echo "Usage: uv-test [-p|--python PY_VER] [pytest args...]"
echo " -p, --python Set Python version (default: \$UV_PY or 3.14)"
echo " -h, --help Show this help"
}
PYVER="${UV_PY:-3.14}"
# Parse only our flags; pass the rest to pytest
while [ $# -gt 0 ]; do
case "$1" in
-p|--python)
shift
[ $# -gt 0 ] || { echo "error: -p/--python requires a version" >&2; exit 2; }
PYVER="$1"; shift ;;
-h|--help) usage; exit 0 ;;
--) shift; break ;;
*) break ;;
esac
done
command -v uv >/dev/null 2>&1 || { echo "error: 'uv' not found in PATH" >&2; exit 127; }
if [ ! -f pyproject.toml ] && [ ! -f setup.py ]; then
echo "error: no project file found (need pyproject.toml or setup.py). Run from project root." >&2
exit 1
fi
exec uv run --python "$PYVER" --isolated --with-editable '.[test]' -- python -m pytest "$@"
Make it executable and put it somewhere in your PATH, then you can run it like this:
uv-test
Or for a specific Python version:
uv-test -p 3.13
And for custom pytest
arguments:
uv-test -k permissions
Or combined:
uv-test -p 3.12 -k permissions -vv
Created 2025-10-08T19:47:48-07:00, updated 2025-10-08T20:21:33-07:00 · History · Edit