Yeah, this is all ultimately because python packaging is a little nuts. If you don’t really understand how the tools work, and you’re trying to use nix which tries to impose some sanity on them, you can easily get stuck with the more quirky projects out there.
If you use pipx
to install your python packages instead of nix most of these issues will magically go away (i.e., start with pipx install poetry
before doing anything else, and use pipx install -q ...
at the end).
Here’s me explaining the magic:
The poetry self add
command adds plugins to poetry. Basically, you’re installing a build tool, but the build tool needs to then also install another component of itself before it can actually build your project.
This blurs the lines of data vs code, which is just brilliant, because it breaks when you make the build tool read-only (which nix imposes as a limitation to make it possible to have declarative configuration - imperatively changing applications on your system leads to insanity).
We can solve this with nix, by making nix install the plugin instead of letting poetry do it itself:
# poetrypoet.nix
let
pkgs = import <nixpkgs> {};
in
pkgs.poetry.withPlugins (_p: [
pkgs.poethepoet
])
nix-shell -p 'import ./poetrypoet.nix'
Yes, this requires knowing all of the stuff I just told you about, and also about an obscure function hidden in the nixpkgs source. But the problem is ultimately that poetry blurs the line of what we call a “package” here.
Yep, pip installs to some global python modules directory, which is also a modification to your python environment. It used to just do that without complaining on other distros, which would have hilarious consequences like breaking ubuntu. Nowadays it doesn’t do that anymore, so at least we have some better tooling around.
The reason pipx
solves all these issues is that it automatically creates an isolated virtualenv to install all your packages into. This virtualenv will not be entirely declarative; The packages can be modified at runtime. The downside of this is that your environment may randomly break, the upside is that you can just blindly follow the instructions of random projects that expect your environment to be breakable.
This breaks apart when you need one virtualenv to hold a set of packages, of course, at that point you need to manually break out the virtualenv
.
But yes, sometimes a VM or distrobox is the only reasonable option. Java projects, for example, are much worse than even the mess of python because of their complexity and the lack of sane build systems altogether.