pip: [2020-resolver] No longer can get list of available versions.
What did you want to do?
I would like to list all the available versions of a package. In the past we would use this:
pip install pip==asdf # any gibberish here :)
Output
ERROR: Could not find a version that satisfies the requirement pip==asdf
ERROR: No matching distribution found for pip==asdf
expected output (pip==20.2.4)
ERROR: Could not find a version that satisfies the requirement pip==asdf (from versions: 0.2, 0.2.1, 0.3, 0.3.1, 0.4,
0.5, 0.5.1, 0.6, 0.6.1, 0.6.2, 0.6.3, 0.7, 0.7.1, 0.7.2, 0.8, 0.8.1, 0.8.2, 0.8.3, 1.0, 1.0.1, 1.0.2, 1.1, 1.2,
1.2.1, 1.3, 1.3.1, 1.4, 1.4.1, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.5.6, 6.0, 6.0.1, 6.0.2, 6.0.3, 6.0.4,
6.0.5, 6.0.6, 6.0.7, 6.0.8, 6.1.0, 6.1.1, 7.0.0, 7.0.1, 7.0.2, 7.0.3, 7.1.0, 7.1.1, 7.1.2, 8.0.0, 8.0.1, 8.0.2,
8.0.3, 8.1.0, 8.1.1, 8.1.2, 9.0.0, 9.0.1, 9.0.2, 9.0.3, 10.0.0b1, 10.0.0b2, 10.0.0, 10.0.1, 18.0, 18.1, 19.0,
19.0.1, 19.0.2, 19.0.3, 19.1, 19.1.1, 19.2, 19.2.1, 19.2.2, 19.2.3, 19.3, 19.3.1, 20.0, 20.0.1, 20.0.2, 20.1b1,
20.1, 20.1.1, 20.2b1, 20.2, 20.2.1, 20.2.2, 20.2.3, 20.2.4, 20.3b1)
Additional information
- Using verbose flag:
pip install -v pip==asdfwe can sorta see that versions. (300 line output, too long to post here) Seems like no extra requests needed. I wasn’t 100% sure if it was the case. - This is useful when debugging failed installation of a requirement.txt, pipenv or other 3rd party package managers
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 38
- Comments: 28 (17 by maintainers)
Links to this issue
Commits related to this issue
- worked around pip update (https://github.com/pypa/pip/issues/9139) — committed to patrick-kidger/signatory by patrick-kidger 3 years ago
- Allow for installation of the latest pypi version Uses `pip install foo==` which will output all available versions to STDERR. The last package is then chosen. This API is deprecated ref https://git... — committed to equinor/komodo by jondequinor 3 years ago
- Allow for installation of the latest pypi version Uses `pip install foo==` which will output all available versions to STDERR. The last package is then chosen. This API is deprecated ref https://git... — committed to equinor/komodo by jondequinor 3 years ago
- Allow for installation of the latest pypi version Uses `pip install foo==` which will output all available versions to STDERR. The last package is then chosen. This API is deprecated ref https://git... — committed to equinor/komodo by jondequinor 3 years ago
- Bump pip from 21.0.1 to 21.1 (PR #2884) Bumps [pip](https://github.com/pypa/pip) from 21.0.1 to 21.1. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pypa/pip/b... — committed to inmanta/inmanta-core by inmantaci 3 years ago
- Bump pip from 21.0.1 to 21.1.1 (PR #2943) Bumps [pip](https://github.com/pypa/pip) from 21.0.1 to 21.1.1. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pypa/p... — committed to inmanta/inmanta-core by inmantaci 3 years ago
@brainwane I disagree with that, actually it’s still useful even when UNINTENTIONALLY getting it. If I did
pip install distlib==0.29.post0and saw:That tells me I just had a silly typo and I wanted
0.2.9.post0. But if I sawIt tells me something else, probably that I have misconfigured my index urls and I should check the pip config. In 20.3.x
This is less helpful again. Is my index misconfigured? Could it find any version at all? Do I just need to wait a moment or clear pip’s cache - maybe I just published this package recently?
pip searchafaik is broken and slated to be removed (https://github.com/pypa/pip/issues/5216). At least, I could not find any way to use it reliably (and couldn’t get it working at all with a devpi-server index).Thank you for mentioning the
--use-deprecated=legacy-resolveroption! For the purposes of keeping the project johnnydep functioning on pip 20.3.x, this helped for now. Currently it scrapes pip’s CLI output in a way that needs careful tweaking and testing each time a new version of pip is released. So here’s a bit of UX feedback, it would be really nice if there was a less fragile way to get:@pfmoore So how do we get that information? A while ago pip moved all package finding code under _internal and made it explicit that a CLI subprocess was the only supported way to use pip from your program. This is arguably an important part of the CLI.
I think that is oversimplifying the problem. It might be true if pip was only a PyPI client, but it’s a lot more than that isn’t it? Pip’s the de facto tool for working with Python packages, whether from PyPI or not, since we don’t really have one in the stdlib.
To repeat again the points in #1884: the PyPI JSON is not in general “the same information” because where pip looks is highly configurable, e.g. we may have another --index-url and then an --extra-index-url and maybe that index is just a simple repository which is supporting a JSON api at all. There are a lot of little details here and doing it in a way that accurately produces the same packages that pip would see would mean reproducing a significant amount of package finder code found within
pip._internal.I believe that at this point this is just a behaviour that many people may have relied on for years. Sometimes things that were not meant to be present but were just become part of what is expected.
I would really love to see this back - it seemed like the most streamlined way to find out what versions one can install. See this highly voted stack answer here.
This has been a canonical feature of Pip for many of its users for at least 6 years now. I’ve given this tip out numerous times at work, I’m probably not the only one. There’s this SO answer - +950 rep on a 10 year-old, very specific question that’s been viewed 280k times. Tooling that uses pip has been scraping this data for years.
If you wish to remove this output, then to appease users you’ll have to add a feature that makes it possible to list it out. And one that is as succinct and streamlined as appending
==. By the looks of it, there’s nothing else possible that comes close.Listing versions by appending
==is, simply put, a good feature.We’ve come to enjoy it due to a happy accident related to how pip handles its arguments. But that doesn’t mean it’s not valuable and shouldn’t be there.
If you’re not going to add
==usage back, then the discussion is probably a waste of time. A longer flag or a subcommand will feel like a chore to type when a version is mistyped. At that point it indeed would be a good idea to create a separate tool, if only it wasn’t for the fact that it would have to clone large chunks of code from Pip in order for the outputs to be relevant for the issue at hand.UX-wise you have to remember you are operating in a regime where each keystroke is a considerable cost. Anyone who uses
==a lot is familiar with the following typing-scheme:pip install package==<kbd>⏎</kbd> → <kbd>↑</kbd><desired_version><kbd>⏎</kbd>or
pip install package==<wrong_version><kbd>⏎</kbd> → <kbd>↑</kbd> <kbd>←BP</kbd> <kbd>←BP</kbd> <kbd>←BP</kbd> …<desired_version><kbd>⏎</kbd>The convenience factor of this is huge. I doubt anyone will be able to come up with anything better.
Trying to fix the lack of that by adding
--list-versionsas an available flag is misguided. Not to bash on @NoahGorny’s idea - pip should have an explicit, user-facing feature that makes it possible to obtain the list. But #8978 should be discussed separately to this issue.IMO
pip searchis, to put it lightly - irrelevant. It produces unreliable and overly verbose results, uses different index frompip install, not to mention theXMLRPC API has been temporarily disabledof PyPI and #5216.Following the workaround noted by @brainwane I’m using this little helper
Then e.g.
Not nice, good enough for now
imo: removing output that helped with diagnosis (a version typo), seems to go against a basic unix philosophy "Write programs which fail in a way that is easy to diagnose".
Hello folks! I had a PR #8978 which proposes a new way to look at the available versions (
pip search <packages> --list-all-versions)If you support this idea, please let folks here know so we can move forward with this offer 😄
cc @ei8fdb
@vityas thank you for this bug report, which I’ve just discussed with pip maintainer @pradyunsg.
I understand what you’re concerned about. It used to be the case that if you ran that particular command, pip would tell you about all the versions of that package available in the index you were hitting (such as PyPI). Now pip doesn’t print that info about versions by default, with the new resolver.
This was not a useful error message for people who UNINTENTIONALLY got it, but it was the only way to get (on the command line) a list of all the available versions of a package on PyPI or on another index.
If you’re hitting PyPI, you can go the release history page for a project, such as https://pypi.org/project/pip/#history , but with the new resolver behavior, currently, there’s no easy way to get this info in the CLI directly and in a concise format. pip hits an index and gets the list, but now doesn’t present it by default. And if you turn up verbosity, you get the info but in a hard-to-use format, as you said.
Right now, in order to expedite the release of pip 20.3 this week. I’m marking it as post-release work.
For now, we advise you to (per the deprecation timeline) opt-out and choose the old resolver behavior for now, using the flag
--use-deprecated=legacy-resolver.But also: you’re bringing further attention to two problems with pip’s functionality more generally. pip has a few functions, such as
pip search, which offer a little bit of discoverability to help users see what is available in package indexes. Pradyun wants to consolidate functionality and design for these features. And we know that pip’s output, especially its--verboseoutput, needs work. So I hope you will please talk to our UX people, @nlhkabu @ei8fdb and @georgiamoon, by signing up for the user experience studies, to help them work on the larger project of making our verbose output and our package discoverability functionality better.Thank you!
It’s definitely not (and never was) a supported way of getting that information. But I can imagine the possibility that we might implement a supported way of getting the same data. Although to be honest, as long as you just want to get the information from PyPI (and don’t need to support extra indexes, or local package repositories) it’s not that hard to write something yourself that gets the same information, using the PyPI JSON interface, plus
packaging.tagsfor doing the wheel compatibility checks.Maybe someone could publish a “PyPI query” package that did things like this? It might be an interesting project for someone who wants to get into working with the packaging ecosystem.
This feature must come back. It is terrible design to remove it. It was very useful to navigate between different package versions. Basically, when an upgrade of a package breaks something, to be able to roll back to the previous version.
@RafalSkolasinski Thanks for sharing your experience! Indeed, we’re getting a lot of demonstrations of Hyrum’s Law as we engage in this work this year. 😃
As you saw in a comment above, when prioritizing what to address and what to leave for later, I decided to leave this particular issue for later. We’ve had to be incredibly limited in what we build and fix with the funding we got to work on pip this year. It runs out at the end of December. One of the things we did with that funding was set up a more systematic way to hear from our users about how you use pip, what features you use, and so on, to help us make better decisions – user experience research and testing. I hope you will sign up for the user experience surveys and share your opinion in more depth that way. (For example, you could share whether you always use PyPI or whether this functionality is important to you when installing from other sources as well.)
And the pip team has no reliable future funding, and can do a lot more if companies that depend on Python packaging tools chip in (here’s the packaging sponsorship program).
Unless I’m missing something, no it wouldn’t. That would remove the ability to get the list of versions entirely.
@MrMino A PR removing the legacy resolver would be great (or even just one that removed the option and fixed the tests, and left actual removal of the old resolver code for later).
I can’t promise I’ll have a lot of time to review such a PR (my review time is almost as limited as my coding time at the moment) but maybe other @pypa/pip-committers could help out there.
Posted Nov 2020. I wonder if that’s what lead to the DDoS(?) of the XMLRPC endpoint.
just for completeness sake, this affects
saltstackas well: https://github.com/saltstack/salt/issues/59100There. It’s even better than the previous thing, at least for me.
WARNINGis probably wrong, but the yellow text is cool™. This could still use some sorting - currently it usesset()to exclude duplicates, which means that ordering might not be correct, for I’m too lazy to do it properly. Not sure if I should uselist(OrderedDict.fromkeys(...))to simply preserve it, ordistutils.LooseVersionto sort explicitly.Some dupes still go through for some reason, but I’m too tired this year to find out why (edit: actually, I just forgot to reinstall pip after patching this, its fixed already).
This is how it looks right now. In case where the library is nowhere to be found (also, when cache is not used):
In case the version is wrong:
When you have multiple indexes specified, the diagnostic will only mention the ones in which the package version/s were found. Having multiple indexes logged looks something like this (some info redacted because I’m NDA-scared):
See you next year.
imo this feature should be brought back in or at least outsourced to a new option thats bit less unwieldy than sudo pip3 --use-deprecated=legacy-resolver install xx==. The new behavoir can be misleading and less useful for the many reasons already stated.
As I mentioned in early December, in a comment above:
FYI, that funding has now run out. As far as I know, no one is currently paid to work on pip (including code review). It’s all volunteers.
@brainwane thanks for your explanation on why this feature (I’m gonna call it a feature as we rely on it in johnnydep, pipgrip, probably more) was deprecated in the new resolver.
Like mentioned above, it would be quite cumbersome and most likely introducing bugs to move away from using this feature in pip, so I’ve dropped support for pip 21 (hoping to loosen that constraint again though!), and will keep an eye out for this issue.
Thanks for all your hard work and responses throughout these exciting times! 🙏