pipx icon indicating copy to clipboard operation
pipx copied to clipboard

Feature request: Option to list available upgrades without performing them

Open Phidica opened this issue 5 years ago • 25 comments

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

Phidica avatar Apr 29 '19 10:04 Phidica

Maybe an option like --dry-run?

cs01 avatar Apr 30 '19 04:04 cs01

Yes, that would work

Phidica avatar Apr 30 '19 12:04 Phidica

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.

cs01 avatar May 01 '19 03:05 cs01

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?

Phidica avatar May 01 '19 11:05 Phidica

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/

Phidica avatar May 01 '19 11:05 Phidica

Looks like this url will work:

https://pypi.org/pypi/PACKAGE/json

cs01 avatar May 12 '19 06:05 cs01

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- )
}

StaticPH avatar Aug 31 '20 21:08 StaticPH

The underlying technical necessity here is the same as #464.

uranusjr avatar Sep 01 '20 00:09 uranusjr

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.

itsayellow avatar Sep 02 '20 21:09 itsayellow

e.g. https://github.com/jwodder/pypi-simple, an interface to the Simple API

itsayellow avatar Sep 05 '20 18:09 itsayellow

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.

itsayellow avatar Oct 24 '20 20:10 itsayellow

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.

uranusjr avatar Oct 24 '20 20:10 uranusjr

Oh, I thought they came from the same place.

itsayellow avatar Oct 24 '20 22:10 itsayellow

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? 🙏

justinmayer avatar Jan 17 '21 09:01 justinmayer

pip has the list --outdated command. Could you hook into that maybe?

J-M0 avatar Jan 20 '21 17:01 J-M0

pip has the list --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.

justinmayer avatar Jan 21 '21 15:01 justinmayer

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?

itsayellow avatar Jan 21 '21 23:01 itsayellow

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

justinmayer avatar Jan 22 '21 08:01 justinmayer

I would also prefer ignoring non-PyPI packages. Thanks for the efforts!

Phidica avatar Jan 22 '21 13:01 Phidica

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

kkovaletp avatar Nov 19 '21 11:11 kkovaletp

PR welcome.

gaborbernat avatar Dec 02 '23 17:12 gaborbernat

I'd like to take over work on this.

chrysle avatar Apr 21 '24 11:04 chrysle