The main problem is that when python goes to do a import <module>
. It will only find one.
So if we have many versions, then it becomes non-deterministic whether a collection of packages will work together.
If a package is very fragile (in terms of dependencies), then something like poetry2nix would probably be a better route to go.
Here’s my saved reply on the matter:
Pinning within python-modules is highly discouraged. This will potentially introduce incompatible versions in a user’s environment as either the new pinned version or the original version will be imported at runtime, breaking one of the packages.
The preference to handling this is to relax version bounds in the “install_requires” field. (could be in setup.py, pyproject.toml, requirements or others). In most cases, packages are still compatible with small API changes which may warrant a major version bump. We use test suites to verify that the package still works correctly.
If the package is still incompatible with the latest major version, then the most proper way to handle this is make an issue with the upstream package to adopt the latest major version. Or if upstream is not very responsive, you are free patch the source to make it compatible.
In very few circumstances, two versions of the same package are allowed to exist if the packages are extremely difficult to package. Some examples of this are tensorflow, which has huge ecosystems built around it and is hard to package. Another is django, which has 2 actively developed versions, and large ecosystems built around each.
One exception to this is applications, due to the way buildPythonApplication
and toPythonApplication
functions work, the related derivations will not bleed dependencies between packages. If the package doesn’t need to be imported by other python modules, then this package would be a good candidate to convert into application. You can look at https://github.com/NixOS/nixpkgs/blob/2211a7cf7498ec326fa66cb81e4cdb2c5a07b10c/pkgs/tools/admin/awscli/default.nix as an example of using an overlay within a python application.
Another valid exception is pinning within the same interpreter version. If a package no longer supports older-but-still-relevant interpreter versions, then you’re free to pin a package for an interpreter. This was very common with python2, but less common amongst python3 interpreters. (e.g. if (pythonOlder "3.8" then <older pkg> else <latest package> ;
)
Info on buildPythonApplication
can be found here.
Info on toPythonApplication
can be found here.