List outdated packages in Python's pipx without upgrading
_`pipx` does not currently provide a built in method of listing outdated packages. A short `bash` function shared in an open GitHub issue provides a workaround._
* Introduction
* Solution
* Resources
## Introduction
I've been using `pipx` to manage my Python application for roughly three years. As the documentation states, "`pipx` installs and runs end-user Python apllications(and their respective dependencies) in isolated environments". I'm able to keep my `pip list` relatively clean as well as isolate my installed applications in separate virtual environments(venvs). Being able to minimize dependency conflicts has alleviated some of the headaches that previously came with installing all my applications and libraries via `pip`. Since I'm also using `pyenv`, I can also install them using different Python versions, if necessary.
I do, however, have one nit to pick with `pipx`. Currently, there is no way to check for available upgrades without actually performing the upgrades. That is, by running `pipx upgrade-all` and, potentially, upgrading all installed applications. This is time consuming as `pipx` needs to go through my entire list of installed applications and does not allow me to review upgradeable packages individually. `pip` has this functionality built in with the command `pip list --outdated`. There is also a separate package for managing `pip` package installations called `pip-check` which I use often and have installed via `pipx`.
Fortunately, a few years ago, I came across this issue: Feature request: Option to list available upgrades without performing them. While the issue remains open after almost seven years, there is some interesting discussion there as well a couple posts containing workable solutions. I've chosen to implement @StaticPH's comment as my preferred solution.
## Solution
pipx-outdated() {
# See: https://github.com/pypa/pipx/issues/149#issuecomment-684042303
echo "OUTDATED PACKAGES:"
while read -sr pyPkgName pyPkgVersion; do
pyPkgURL="https://pypi.org/pypi/${pyPkgName}/json"
pypi_latest="$(curl -sS "${pyPkgURL}" | jq --raw-output '.info.version')"
[ "$pyPkgVersion" != "$pypi_latest" ] && printf "%s\n\tCurrent: \
%s\tLatest: %s\n" "$pyPkgName" "$pyPkgVersion" "$pypi_latest"
done <<( pipx list | grep -o 'package.*,' | tr -d ',' | cut -d ' ' -f 2- )
}
The `pipx-outdated` function greps through the output of `pipx list` to get the package name and its currently installed version. Next, using `curl`, it constructs the PyPi package URL and extracts the latest version from the available json file and compares the installed version to the latest. If there is a difference between the two, a list of outdated packages is print out to the console. While this function may ignore dev or alpha release, it is adequate for my use.
At this point, I can selectively upgrade the packages that I am interested or pass `pipx upgrade` only the packages I choose to upgrade at this time. Adding this to my `.bash_aliases` file allows me to run this whenever its needed.
Here's an example of the output of the `pipx-outdated` function showing two packages that have updates available.
~$ pipx-outdated
OUTDATED PACKAGES:
glances
Current: 4.5.2 Latest: 4.5.3
hike
Current: 1.3.0 Latest: 1.4.0
I could choose either to upgrade a single package `pipx upgrade ruff` or I could upgrade both simultaneously with the command `pipx upgrade glances ruff`.
While it may be convenient to have this feature eventually integrated into the `pipx` package proper, I'm grateful to the folks who create and share solutions to paper-cuts as well as the developers who maintain and support the `pipx` package.
## Resources
* pipx code repository
* pipx project page
* pipx documentation
* pipx-outdated function
* pip project page
* pip-check project page
A new blog post by me:
"List outdated packages in Python's pipx without upgrading"
Solving a papercut in pipx with a small bash function.
suburbanalities.blogspot.com/2026/03/list-outdated-pa...
#Python #pipx #papercut #Blog #Suburbanalities #Bash
1
3
0
0