Some notes on upgrading programs with Python's pip
My primary use of Python's pip package manager is to install programs
like the Python LSP server; I may install these
into either a contained environment (a virtual environment or a
PyPy one) or as a user package with '
install --user'. In either case, the day will come when there's a
new version of the Python LSP server (or whatever) and I want to
update to it. As I noted down back in my pip cheatsheet, the basic command I want here is '
--upgrade <package>', possibly with '
--user' as well. However,
it turns out that there are some complexities and issues here, which
ultimately come about because pip is not the same sort of package
manager as Fedora's DNF or Debian's apt.
The conventional way a Unix package manager such as DNF operates is that when you ask it to upgrade things, it upgrades everything that has new versions available. Pip doesn't behave this way. By default, it only upgrades the package that you asked it to, and doesn't upgrades any dependencies unless what you currently have doesn't satisfy the requirements of the new version of the upgraded package. Over enough time, this will often give you significantly out of date dependencies where you're missing out on improvements and bug fixes they've made even if your main package is theoretically fine with the old versions you have installed.
(This generally also means that the versions you've wound up with don't match what you'd get if you deleted everything and reinstalled from scratch, assuming you kept track of what top level packages you installed.)
This can be controlled (to some degree) by the
option to '
This can be used to switch pip to an "eager" upgrade strategy, where
it also upgrades dependencies to the latest available version that
satisfies the requirements. You can set this as a default through
pip's configuration files. However,
this eager upgrading process is not flawless (as pip error messages
may occasionally point out); you may wind up with versions of
dependencies that satisfy the program, but not other things you
have sitting around (including as globally installed modules from
your operating system). Despite this, I've set up a
~/.config/pip/pip.conf to make the eager mode my default, because
it's more like how I want package management for programs to work;
normally I want to be using the latest and best version of everything.
(Usefully, you can tell if your pip.conf is working by what '
install --help' reports as the default for
A Unix package manager like apt (almost) always removes the older
version of a package when you upgrade to a newer one, and in fact
many Unix packages can't have multiple versions installed at once.
Pip somewhat apes this, but under some circumstances you can
apparently wind up with older versions still present on disk. This
especially matters if you decide to uninstall a package, because
pip uninstall' seems to only remove the most recent version (what
pip list' will show you as the version). If pip has left multiple
versions sitting around, you may need a number of '
invocations to get the package gone from '
pip list'. Alternatively,
you can go to the appropriate location (such as
~/.local/lib/python3.X/site-packages') and manually remove all
of the directories.