-
Notifications
You must be signed in to change notification settings - Fork 456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dependency management (file requirements.txt and friends) is far too lenient: Too old versions and incompatible new versions. #3734
Comments
I agree that the minimum dependencies listed in our On the other hand, the maximum dependency versions should not be limited, unless the package has a track record of breaking backwards compatibility. There should be no pinning, especially in The problem with dependencies in Python is caused by Python’s package management being awful, 14 competing standards and all. Python ties its packages to an environment — which might be system-wide (including user packages, but that doesn’t matter) or virtual. There are three main ways in which someone may install Nikola: in a venv, system/user-wide with pip, or using their system package manager. If someone is using a venv exclusively to run Nikola, everything would be fine, and we could be using pinned dependencies or very narrow ranges (maintenance burden notwithstanding). But if someone is using a system-wide install, we could cause total breakage if we demand very specific versions. Things are even worse if you include distro packages into the mix: Nikola is packaged in some distros, like Fedora, Arch Linux, or Gentoo. The way Python works means there is only one version of Package versioning is hard, and different entities have different approaches to backwards compatibility. Microsoft will fight tooth and nail to keep things compatible (I have done some cursed package combinations in the .NET land, mixing 5-year-old versions with the latest-and-greatest), but CPython is eager to break stuff (#3719 is one example, but many things are removed with a 2-year warning). The packages Nikola depends on have many different maintainers with different views on backwards compatibility. Some of them follow semver, some follow a scheme detached from backwards compatibility, and some of them don’t have a predictable version numbering scheme. And even then, if we say To sum up: some things can certainly be improved, and the versions in |
I have no "magic bullet" for the upper version limit problem. My personal intuition would be: Let us trust everybody is using semantic versioning. That means, "pin to the same major version we tested". We also could have something automatic that alerts us of stuff releasing a new major version, so we can test that before relaxing our requirements to accept it. So far the theory. In practice, semantic versioning is largely not being followed in the Python world. 23% of all of our dependencies and transitive dependencies sport a version number of So far for the bad news. For the good news, at least I have some idea for the other end of the problem. We could generate a Does that sound like something you'd merge if I managed to code it? |
I would accept testing of |
I don't like upper version pins (unless needed for explicitly known incompatibilities), I've seen them cause problems with dependent projects and users too often... If we do upper version pins, we really need test infrastructure that keeps track of new major releases and runs tests with these. |
"with no >= anywhere" Why not, Chris? I thought rather to the opposite: Judiciously ruling out ancient version seems to be the no-brainer here, though some effort in practice. It's the future versions that is the difficult part, even conceptually. Or at least that's what I thought. Not ruling out ancient versions essentially claims, e.g., "Nikola is fine with any version of Pygments that ever existed." Why would we want to claim that if we know it is not true? |
Fortunately, Pypi is quite scriptable / can be scraped easily. Here is a list of all versions of the primary requirements of Nokia currently available on Pypi: |
I might have messed up the equality signs. I’m against pinning the maximum/upper versions. |
During the last days, my PC has tried many combinations of dependency versions to see whether the Nikola tests still run with those or don't. "Experimental computer science." It is not done with that yet. But the oldest requirements known to me that make the tests pass are (output of
This is the tests without coverage reports (to speed up things). |
After #3744 has been merged, it is possible to create one version of Are you interested in the script itself, or only in the result (the latter being in #3744)? |
(The script is far from perfect. There could be even older versions that, too, make the tests succeed. In particular, if several of our dependencies depend on certain versions of each other without announcing that fact to pip.) |
You can post the script in this issue for future reference, we probably don’t need to add it to the repository. |
find_oldest_working_dependencies.zip actually has two scripts.
The scripts want to sit in a subdirectory of Deficiencies of the second script:
|
Environment
Python Version: 3.9
Nikola Version: Git b96f05a
Operating System: Debian Bullseye
Description:
The present Nikola dependency version requirements are far too lenient.
I wish to raise two separate problems with the present files
requirements*.txt
files:Allowing too new versions
Nikola allows very new versions of its dependencies. When some library introduces incompatible changes and upgrades to a new major version (in full compliance with semver), any unsuspecting user who does
pip install Nikola[extras]
might be the first person in the world that actually mixes that version with Nikola. And it may break.In such a scenario, I see no fault with our dependency, nor with the user, so the fault lies with Nikola.
Some moral equivalent of this happened to me, when a pull request of mine collided with a new, incompatible version of
lxml
that happened to come out between the time when I had set up myvenv
and the time that pull request was tested, giving rise to #3732.Allowing too old versions
I fiddled a bit to find the oldest versions of all Nikola dependencies that would install on my machine and still satisfy all Nikola dependencies. The result is requirements-also_doesntwork.txt. Running
pytest
with those ancient packages installed fails.Analyzing that particular failure, I found that a requirement
Pygments>=1.6
had been added torequirements.txt
with git eab48d8 on 2014-07-17. Later, 2020-03-19 (git 7b792fe) and again 2022-04-24 (7e2fd4f), code was added that usespygments.formatters._formatter_cache
. That attribute does not yet exist in Pygments 1.6. So ever since then, Nikola was boasting to be able to run with that old Pygments version while in fact it could not. I believe this to be just a tip of an iceberg and there are many more compatibility problems of this sort hiding in the code.The text was updated successfully, but these errors were encountered: