How to upgrade all Python packages with pip
Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Is it possible to upgrade all Python packages at one time with pip ? Note: that there is a feature request for this on the official issue tracker.
Beware software rot—upgrading dependencies might break your app. You can list the exact version of all installed packages with pip freeze (like bundle install or npm shrinkwrap ). Best to save a copy of that before tinkering.
If you want to update a single package and all of its dependencies (arguably a more sensible approach), do this: pip install -U —upgrade-strategy eager your-package
I use PowerShell 7 and currently I use this one-liner: pip list —format freeze | %
For those wondering like me, the was until recently pip didn’t have a dependency resolver. github.com/pypa/pip/issues/4551
57 Answers 57
There isn’t a built-in flag yet. Starting with pip version 22.3, the —outdated and —format=freeze have become mutually exclusive. Use Python, to parse the JSON output:
pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))"
pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
For older versions of pip :
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
- The grep is to skip editable («-e») package definitions, as suggested by @jawache. (Yes, you could replace grep + cut with sed or awk or perl or. ).
- The -n1 flag for xargs prevents stopping everything if updating one package fails (thanks @andsens).
Note: there are infinite potential variations for this. I’m trying to keep this answer short and simple, but please do suggest variations in the comments!
Right 🙁 The issue now lives at github.com/pypa/pip/issues/59 . But every suggestion seems to be answered with «Yeah, but I’m too sure if X is the right way to do Y». Now is better than never? Practicality beats purity? 🙁
It also prints those packages that were installed with a normal package manager (like apt-get or Synaptic). If I execute this pip install -U , it will update all packages. I’m afraid it can cause some conflict with apt-get.
How about changing grep to: egrep -v ‘^(\-e|#)’ (i get this line when running it on ubuntu 12.10: «## FIXME: could not find svn URL in dependency_links for this package:».
I’d throw in a tee before doing the actual upgrade so that you can get a list of the original verisons. E.g. pip freeze —local | tee before_upgrade.txt | . That way it would be easier to revert if there’s any problems.
I added -H to sudo to avoid an annoying error message: $ pip freeze —local | grep -v ‘^\-e’ | cut -d = -f 1 | xargs -n1 sudo -H pip install -U
To upgrade all local packages, you can install pip-review :
After that, you can either upgrade the packages interactively:
$ pip-review --local --interactive
pip-review is a fork of pip-tools . See pip-tools issue mentioned by @knedlsepp. pip-review package works but pip-tools package no longer works. pip-review is looking for a new maintainer.
pip-review works on Windows since version 0.5.
@mkoistinen It’s a good tool but until it’s merged in PIP it means installing something additional which not everyone may desire to do.
You can use the following Python code. Unlike pip freeze , this will not print warnings and FIXME errors. For pip < 10.0.1
import pip from subprocess import call packages = [dist.project_name for dist in pip.get_installed_distributions()] call("pip install --upgrade " + ' '.join(packages), shell=True)
For pip >= 10.0.1
import pkg_resources from subprocess import call packages = [dist.project_name for dist in pkg_resources.working_set] call("pip install --upgrade " + ' '.join(packages), shell=True)
This works amazingly well… It’s always so satisfying when a task takes a REALLY long time… and gives you a bunch of new stuff! PS: Run it as root if you’re on OS X!
Is there no way to install using pip without calling a subprocess? Something like import pip pip.install(‘packagename’) ?
@BenMezger: You really shouldn’t be using system packages in your virtualenv. You also really shouldn’t run more than a handful of trusted, well-known programs as root. Run your virtualenvs with —no-site-packages (default in recent versions).
Thumbs up for this one, the chosen answer (above) fails if a package can’t be found any more. This script simply continues to the next packages, wonderful.
The following works on Windows and should be good for others too ( $ is whatever directory you’re in, in the command prompt. For example, C:/Users/Username).
$ pip freeze > requirements.txt
Open the text file, replace the == with >= , or have sed do it for you:
$ pip install -r requirements.txt --upgrade
If you have a problem with a certain package stalling the upgrade (NumPy sometimes), just go to the directory ($), comment out the name (add a # before it) and run the upgrade again. You can later uncomment that section back. This is also great for copying Python global environments.
Another way:
I also like the pip-review method:
py2 $ pip install pip-review $ pip-review --local --interactive py3 $ pip3 install pip-review $ py -3 -m pip-review --local --interactive
You can select ‘a’ to upgrade all packages; if one upgrade fails, run it again and it continues at the next one.
You should remove requirements.txt ‘s ==
@youngminz I would recommand a quick ‘Replace all «==» > «>=» ‘ in your editor/ide before running ‘pip install. ‘ to fix this
If the shell you use is bash, you can shorten it into one command via pip3 install -r <(pip3 freeze) --upgrade Effectively, <(pip3 freeze) is an anonymous pipe, but it will act as a file object
Use pipupgrade! . last release 2019
pip install pipupgrade pipupgrade --verbose --latest --yes
pipupgrade helps you upgrade your system, local or packages from a requirements.txt file! It also selectively upgrades packages that don’t break change.
pipupgrade also ensures to upgrade packages present within multiple Python environments. It is compatible with Python 2.7+, Python 3.4+ and pip 9+, pip 10+, pip 18+, pip 19+.
Note: I’m the author of the tool.
Seems to have some problems: Checking. 2020-03-16 11:37:03,587 | WARNING | Unable to save package name. UNIQUE constraint failed: tabPackage.name 2020-03-16 11:37:13,604 | WARNING | Unable to save package name. database is locked 2020-03-16 11:37:13,609 | WARNING | Unable to save package name. database is locked
It seems that this will upgrade all packages to the latest version and that may break some dependencies.
This worked perfectly for me. So it appears this came a long way since it was originally mentioned and some of the earlier complaints. Not sure why there aren’t easier commands that work but this worked like a charm!
Windows version after consulting the excellent documentation for FOR by Rob van der Woude:
for /F "delims===" %i in ('pip freeze') do pip install --upgrade %i
for /F «delims= » %i in (‘pip list —outdated’) do pip install -U %i Quicker since it’ll only try and update «outdated» packages
@RefaelAckermann I suspect this will be slower than the original 🙂 To know which packages are outdated pip has to first check what’s the latest version of each package. It does exactly the same as the first step when updating and does not proceed if there’s no newer version available. However in your version pip will check versions two times, the first time to establish the list of outdated packages and the second time when updating packages on this list.
@RefaelAckermann Spinning up pip is order of magnitude faster than checking version of a package over network so that’s number of checks which should be optimized not number of spin ups. Mine makes n checks, yours makes n+m checks.
+1 — It’s 6.20.2019, I’m using Python 3.7.3 on WIndows 10, and this was the best way for me to update all my local packages.
Need to skip the first two lines of the output: for /F «skip=2 delims= » %i in (‘pip list —outdated’) do pip install —upgrade %i . If this is run from a batch file, make sure to use %%i instead of %i . Also note that it’s cleaner to update pip prior to running this command using python -m pip install —upgrade pip .
This option seems to me more straightforward and readable:
pip install -U `pip list --outdated | awk 'NR>2 '`
The explanation is that pip list —outdated outputs a list of all the outdated packages in this format:
Package Version Latest Type --------- ------- ------ ----- fonttools 3.31.0 3.32.0 wheel urllib3 1.24 1.24.1 wheel requests 2.20.0 2.20.1 wheel
In the AWK command, NR>2 skips the first two records (lines) and selects the first word of each line (as suggested by SergioAraujo, I removed tail -n +3 since awk can indeed handle skipping records).
The following one-liner might prove of help:
pip install -U `pip list --outdated | awk 'NR>2 '`
pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))" | xargs -n1 pip install -U
pip list —format freeze —outdated | sed ‘s/=.*//g’ | xargs -n1 pip install -U
pip list --format freeze --outdated | sed 's/(.*//g' | xargs -n1 pip install -U
xargs -n1 keeps going if an error occurs.
If you need more «fine grained» control over what is omitted and what raises an error you should not add the -n1 flag and explicitly define the errors to ignore, by «piping» the following line for each separate error:
Here is a working example:
pip list --format freeze --outdated | sed 's/=.*//g' | sed 's/^.*//' | sed 's/^.*//' | xargs pip install -U
Had to add filters for lines beginning with ‘Could’ and ‘Some’ because apparently pip sends warnings to stdout 🙁
You can just print the packages that are outdated:
pip freeze | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'
Inside a virtualenv, I do it like this: pip freeze —local | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 ‘LATEST:’
Nowadays you can also do that with python -m pip list outdated (though it’s not in requirements format).
More Robust Solution
pip3 freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 . ; pip3 install -U \1/p' |sh
For pip, just remove the 3s as such:
pip freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 . ; pip install -U \1/p' |sh
OS X Oddity
OS X, as of July 2017, ships with a very old version of sed (a dozen years old). To get extended regular expressions, use -E instead of -r in the solution above.
Solving Issues with Popular Solutions
This solution is well designed and tested 1 , whereas there are problems with even the most popular solutions.
- Portability issues due to changing pip command line features
- Crashing of xargs because of common pip or pip3 child process failures
- Crowded logging from the raw xargs output
- Relying on a Python-to-OS bridge while potentially upgrading it 3
The above command uses the simplest and most portable pip syntax in combination with sed and sh to overcome these issues completely. Details of the sed operation can be scrutinized with the commented version 2 .
[1] Tested and regularly used in a Linux 4.8.16-200.fc24.x86_64 cluster and tested on five other Linux/Unix flavors. It also runs on Cygwin64 installed on Windows 10. Testing on iOS is needed. [2] To see the anatomy of the command more clearly, this is the exact equivalent of the above pip3 command with comments:# Match lines from pip's local package list output # that meet the following three criteria and pass the # package name to the replacement string in group 1. # (a) Do not start with invalid characters # (b) Follow the rule of no white space in the package names # (c) Immediately follow the package name with an equal sign sed="s/^([^=# \t\\][^ \t=]*)=.*" # Separate the output of package upgrades with a blank line sed="$sed/echo" # Indicate what package is being processed sed="$sed; echo Processing \1 . " # Perform the upgrade using just the valid package name sed="$sed; pip3 install -U \1" # Output the commands sed="$sed/p" # Stream edit the list as above # and pass the commands to a shell pip3 freeze --local | sed -rn "$sed" | sh
[3] Upgrading a Python or PIP component that is also used in the upgrading of a Python or PIP component can be a potential cause of a deadlock or package database corruption.