pipx
pipx copied to clipboard
Feature request: Option to list available upgrades without performing them
I would like to see this as an option to upgrade
and upgrade-all
, where in the case of the former it would tell you if an upgrade is available for the given package, and in the latter it would list the packages for which an upgrade is available
Maybe an option like --dry-run
?
Yes, that would work
I started implementing this using pip search PACKAGE
, but it does not do exact matching, nor can it (https://github.com/pypa/pip/issues/3354). If there is an API pipx can use, I am happy to add it.
Another way to implement this would be to install to a temporary directory, get the version, then erase the temporary directory, but I am going to hold off on that.
Hmm, I didn't realise pip search
was so fraught with troubles. And it seems they may even consider disabling it in the future (pypa/pip#5216) without a better API powering it
It seems that running pip install <name>==
will prompt an error message (because a version number is missing after the ==
) containing a list of versions which are available. Eg,
$ pip3 install pipx==
Collecting pipx==
Could not find a version that satisfies the requirement pipx== (from versions: 0.1.0, 0.12.0.0, 0.12.0.1, 0.12.0.2, 0.12.0.3, 0.12.0.4, 0.12.1.0, 0.12.2.0, 0.12.3.0, 0.12.3.1, 0.12.3.2, 0.12.3.3, 0.13.0.0b1, 0.13.0.0, 0.13.0.1, 0.13.1.0)
No matching distribution found for pipx==
Would parsing this output be acceptable for finding the latest available version of a package?
Studying the debug output of pip
, it appears this is internally implemented by analysing the links on the page https://pypi.python.org/simple/<name>/
eg https://pypi.python.org/simple/pipx/
Looks like this url will work:
https://pypi.org/pypi/PACKAGE/json
Not sure if it will be of much use to others, but I wrote a proof-of-concept bash function that does the job well enough, if not very elegantly. I use this on a machine with Bash4.4 and GNU coreutils, but I don't think I used anything that wont also work with the BSD counterparts.
pipx-outdated() {
echo "OUTDATED PACKAGES:"
while read -sr pyPkgName pyPkyVersion; do
local pypi_latest="$(curl -sS https://pypi.org/simple/${pyPkgName}/ | grep -o '>.*</' | tail -n 1 | grep -o -E '[0-9]([0-9]|[-._])*[0-9]')"
[ "$pyPkyVersion" != "$pypi_latest" ] && printf "%s\n\tCurrent: %s\tLatest: %s\n" "$pyPkgName" "$pyPkyVersion" "$pypi_latest"
done < <( pipx list | grep -o 'package.*,' | tr -d ',' | cut -d ' ' -f 2- )
}
The underlying technical necessity here is the same as #464.
Yes, code that leverages the pip Simple API is probably the way to go for specific searches. It's a shame the return is in HTML instead of some more data-oriented format, but as mentioned in #464 there are python libraries to help parse the html to usable data. I'm not sure which of them is the best and/or actively-developed.
e.g. https://github.com/jwodder/pypi-simple, an interface to the Simple API
https://discuss.python.org/t/potential-inconsistency-w-pep-503-simple-repo-api/3571/4 The quote:
That’s correct, pretty much nothing uses /simple/ as far as I’m aware. It’s huge and also doesn’t get purged regularly so it’s usually out of date anyways.
seems a little worrying to me to use the Simple API as a trusted reference.
The simple API is a trusted source. The comment you’re referencing is taking about the /simple/
page specifically, which lists all packages on an index, that is not relevant here.
Oh, I thought they came from the same place.
Now that Pipx 0.16 has been released with the ability to introspect package metadata, any chance someone could take a look at adding a pipx outdated
command? 🙏
pip
has the list --outdated
command. Could you hook into that maybe?
pip
has thelist --outdated
command. Could you hook into that maybe?
A few days ago I added a (not-yet-published) stanza to my up
Fish shell plugin that does exactly that, since pipx list --outdated
does not exist yet. But hooking into pip list --outdated
is not as straightforward as it might seem at first glance. For example, the output of pip list --outdated
includes dependencies and Python packaging infrastructure that is irrelevant to what we actually want to know — that is, whether the package we Pipx-installed is out-of-date. Here's the output for the pre-commit
virtual environment, which itself is up-to-date but includes output for other out-of-date supporting packages that ostensibly we do not care about:
~ ➤ $HOME/.local/pipx/venvs/pre-commit/bin/python -m pip list --outdated --disable-pip-version-check
Package Version Latest Type
---------- ------- ------ -----
PyYAML 5.3.1 5.4.1 wheel
setuptools 51.1.2 51.3.3 wheel
virtualenv 20.3.1 20.4.0 wheel
Ergo, I added a Pipx stanza to my up outdated
function that does this:
- Pipe
pipx list
output into a variable. - Extract package names from this list and iterate over them.
- Run
pip list --outdated
for the target package (as shown above). - If a given line in the output includes the target package name, extract the old and new version numbers.
- Print the package name, old version, and new version to the console.
I think this would be done much better within Pipx itself instead of using Fish shell, but at least I've validated my approach and have a solution that works for me in the interim.
I've started working on this.
One question, do people have an opinion on how to handle non-PyPI packages (e.g. from git or from a URL)? Right now it appears that pip list --outdated
actually attempts to look up such packages on PyPI even if they don't exist there. It normally just doesn't list them in the outdated list because it can't find the latest version.
My main question is the default behavior for pipx--would the user want to see a list of packages where the "latest version is unknown" or just ignore any git- or URL- based packages for the purposes of pipx list --outdated
?
Yay! That's great, Matthew. Very exciting.
Regarding your question, I suggest we ignore any packages for which we can’t reliably indicate related version information.
Regarding the output, my thoughts are that it would look like this:
~ ➤ pipx list --outdated
ansible: 2.9.14 < 2.10.5
howdoi: 2.0.7 < 2.0.10
pre-commit: 2.8.1 < 2.9.3
I would also prefer ignoring non-PyPI packages. Thanks for the efforts!
Is there any progress on this so far?
I have update notifier, which currently checks for updates of my globally installed pip packages by executing pip3 list --outdated --not-required --format json | jq
I'd really like to have same functionality for pipx as well
PR welcome.
I'd like to take over work on this.