On using reproducible Python development environments
One of the things I find annoying about using Python is that there
are so many ways of making the development environment of a package or
set of scripts reproducible. I have a repository that
contains several Python scripts that help me with various tasks, mostly
related to qBittorrent. Maybe one or two of these scripts can be
separated out into a distinct, individual package, but it’s generally
more convenient for me to have a directory-level development environment
activated with direnv where I can run the other scripts too. I’ve been
using nix-shell with a shell.nix file, but this tends to
require that I learn the Nix expression language in order to configure
shell.nix. I don’t like using tools I don’t fully understand, and I’m
not willing to prioritize learning Nix. It would be nice if I could just
use a TOML file to declare everything I need, similar to pyproject.toml,
and nix-shell would read this instead of shell.nix. As far
as I know, the Nix language doesn’t have a way to map the TOML structure
to Nix expressions. I’ve tried devenv.sh, but this adds extra files and
cruft that I don’t want polluting my development environment. If I use a
plain requirements.txt file with a virtualenv, it can’t pull in the
Python tools I use, like black, isort, bpython, and pyright.
One solution I’m leaning toward is to install these tools with pipx,
where they’d be available to my shell environment relative to my home
directory at ~/.local/bin/, and use something like
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
echo "layout python3" > .envrc
direnv allow
printf ".venv\n.direnv\n" | tee -a .gitignore
direnv would activate the virtualenv, which in turn would be relative to that git repository directory.
I’m open to suggestions and am curious how others might have solved this problem. Feel free to reach out to me in the Fediverse at @hyperreal@fedi.hyperreal.coffee.