Est-il possible de mettre à jour tous les paquets Python à la fois avec pip
?
Notez qu'il y a une demande de fonctionnalité pour cela sur le traqueur de problème officiel.
Il n'y a pas encore d'indicateur intégré, mais vous pouvez utiliser
pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
Remarque: il existe des variations de potentiel infinies pour cela. J'essaie de garder cette réponse courte et simple, mais veuillez suggérer des variations dans les commentaires!
Dans l'ancienne version de pip
, vous pouvez utiliser ceci à la place:
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
La grep
consiste à ignorer les définitions de paquetages modifiables ("-e"), comme suggéré par @jawache. (Oui, vous pouvez remplacer grep
+ cut
par sed
ou awk
ou Perl
ou ...).
L’indicateur -n1
pour xargs
empêche d’arrêter tout si la mise à jour d’un paquet échoue (merci @andsens ).
Vous pouvez utiliser le code Python suivant. Contrairement à pip freeze
, cela n’imprimera pas les avertissements et les erreurs FIXME .Pour 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)
Pour 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)
Mettre à jour tous les paquets locaux; vous pouvez utiliser pip-review
:
$ pip install pip-review
$ pip-review --local --interactive
pip-review
est un fork de pip-tools
. Voir pip-tools
issue mentionné par @knedlsepp . Le package pip-review
fonctionne, mais le package pip-tools
ne fonctionne plus.
pip-review
fonctionne sous Windows depuis la version 0.5 .
Fonctionne sous Windows. Cela devrait aussi être bon pour les autres . ($ Est le répertoire dans lequel vous vous trouvez, dans l'invite de commande, par exemple C:/Utilisateurs/Nom d'utilisateur>)
faire
$ pip freeze > requirements.txt
ouvrez le fichier texte, remplacez le == par> =
alors fais
$ pip install -r requirements.txt --upgrade
Si vous rencontrez un problème avec un certain paquet bloquant la mise à niveau (numpy parfois), allez simplement dans le répertoire ($), commentez le nom (ajoutez un # avant) et relancez la mise à niveau. Vous pouvez plus tard décommenter cette section. C'est aussi très bien pour copier des environnements globaux python.
J'aime aussi la méthode pip-review:
py2
$ pip install pip-review
$ pip-review --local --interactive
py3
$ pip3 install pip-review
$ py -3 -m pip_review --local --interactive
Vous pouvez sélectionner 'a' pour mettre à jour tous les paquets; si une mise à niveau échoue, exécutez-la à nouveau et continue à la suivante.
Version Windows après consultation excellente documentation pour FOR
de Rob van der Woude
for /F "delims===" %i in ('pip freeze -l') do pip install -U %i
Vous pouvez simplement imprimer les paquets périmés
pip freeze | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'
Le one-liner suivant pourrait s’avérer utile:
pip list --format freeze --outdated | sed 's/(.*//g' | xargs -n1 pip install -U
xargs -n1
continue si une erreur survient.
Si vous avez besoin d'un contrôle plus fin sur ce qui est omis et ce qui soulève une erreur, vous ne devez pas ajouter l'indicateur -n1
et définir explicitement les erreurs à ignorer, en "dirigeant" la ligne suivante pour chaque erreur séparée:
| sed 's/^<First characters of the error>.*//'
Voici un exemple de travail:
pip list --format freeze --outdated | sed 's/(.*//g' | sed 's/^<First characters of the first error>.*//' | sed 's/^<First characters of the second error>.*//' | xargs pip install -U
Cette option me semble plus simple et lisible:
pip install -U `pip list --outdated | tail -n +3 | awk '{print $1}'`
L'explication est que pip list --outdated
génère une liste de tous les packages obsolètes dans ce 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
tail -n +3
ignore les deux premières lignes et awk '{print $1}'
sélectionne le premier mot de chaque ligne.
Cela semble plus concis.
pip list --outdated | cut -d ' ' -f1 | xargs -n1 pip install -U
Explication:
pip list --outdated
obtient des lignes comme celles-ci
urllib3 (1.7.1) - Latest: 1.15.1 [wheel]
wheel (0.24.0) - Latest: 0.29.0 [wheel]
Dans cut -d ' ' -f1
, -d ' '
définit "espace" comme délimiteur, -f1
signifie la première colonne.
Ainsi, les lignes ci-dessus deviennent:
urllib3
wheel
puis passez-les à xargs
pour exécuter la commande, pip install -U
, avec chaque ligne sous forme d'arguments ajoutés
-n1
limite le nombre d'arguments passés à chaque commande pip install -U
à 1
Solution plus robuste
Pour pip3, utilisez ceci:
pip3 freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip3 install -U \1/p' |sh
Pour pip, il suffit de retirer les 3 en tant que tels:
pip freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip install -U \1/p' |sh
OSX Oddity
OSX, à partir de juillet 2017, est livré avec une version très ancienne de sed (une dizaine d’années). Pour obtenir des expressions régulières étendues, utilisez -E au lieu de -r dans la solution ci-dessus.
Résoudre les problèmes avec des solutions populaires
Cette solution est bien conçue et testée1, alors qu’il ya des problèmes même avec les solutions les plus populaires.
La commande ci-dessus utilise la syntaxe pip la plus simple et la plus portable en combinaison avec sed et sh pour résoudre ces problèmes complètement. Les détails de l'opération sed peuvent être examinés avec la version commentée2.
Détails
[1] Testé et utilisé régulièrement dans un cluster Linux 4.8.16-200.fc24.x86_64 et testé sur cinq autres versions de Linux/Unix. Il fonctionne également sur Cygwin64 installé sur Windows 10. Un test sur iOS est nécessaire.
[2] Pour voir plus clairement l'anatomie de la commande, il s'agit de l'équivalent exact de la commande pip3 ci-dessus avec commentaires:
# 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] La mise à niveau d'un composant Python ou PIP qui est également utilisé dans la mise à niveau d'un composant Python ou PIP peut être une cause potentielle d'un blocage ou de la corruption de la base de données de packages.
J'ai eu le même problème avec la mise à niveau. Le fait est que je ne mets jamais à jour tous les paquets. Je ne mets à niveau que ce dont j'ai besoin, car le projet peut échouer.
Parce qu'il n'y avait pas de moyen facile de mettre à jour paquet par paquet et de mettre à jour le fichier Requirements.txt, j'ai écrit ceci pip-upgrader qui met également à jour les versions dans votre fichier requirements.txt
pour les packages choisis (ou tous les packages).
Installation
pip install pip-upgrader
_ {Usage} _
Activez votre virtualenv (important, car il installera également les nouvelles versions des packages mis à niveau dans le virtualenv actuel).
cd
dans le répertoire de votre projet, puis exécutez:
pip-upgrade
_ {Utilisation avancée} _
Si les exigences sont placées dans un emplacement non standard, envoyez-les sous forme d'arguments:
pip-upgrade path/to/requirements.txt
Si vous savez déjà quel paquet vous voulez mettre à jour, envoyez-les simplement comme arguments:
pip-upgrade -p Django -p celery -p dateutil
Si vous devez effectuer une mise à niveau vers une version préliminaire ou postérieure, ajoutez l'argument --prerelease
à votre commande.
Divulgation complète: j'ai écrit ce paquet.
De https://github.com/cakebread/yolk :
$ pip install -U `yolk -U | awk '{print $1}' | uniq`
cependant, vous devez d'abord obtenir du jaune:
$ Sudo pip install -U yolk
Version à une ligne de @ La réponse de Ramana .
python -c 'import pip, subprocess; [subprocess.call("pip install -U " + d.project_name, Shell=1) for d in pip.get_installed_distributions()]'
`
si vous utilisez virtualenv et si vous voulez simplement mettre à jour les paquets added à votre virtualenv, vous voudrez peut-être:
pip install `pip freeze -l | cut --fields=1 -d = -` --upgrade
$ pip install pipupgrade
$ pipupgrade --latest --yes
pipupgrade vous aide à mettre à niveau votre système, local ou vos paquets, à partir d'un fichier requirements.txt
! Il met également à niveau de manière sélective les paquets qui ne cassent pas le changement. Compatible avec Python2.7 +, Python3.4 + et pip9 +, pip10 +, pip18 +.
NOTE: je suis l'auteur de l'outil.
Solution Windows Powershell
pip freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}
La solution la plus simple et la plus rapide que j'ai trouvée dans la discussion sur le problème pip est la suivante:
Sudo -H pip install pipdate
Sudo -H pipdate
Vous pouvez essayer ceci:
for i in ` pip list|awk -F ' ' '{print $1}'`;do pip install --upgrade $i;done
Le jaune assez étonnant rend cela facile.
pip install yolk3k # don't install `yolk`, see https://github.com/cakebread/yolk/issues/35
yolk --upgrade
Pour plus d'informations sur le jaune: https://pypi.python.org/pypi/yolk/0.4.3
Il peut faire beaucoup de choses que vous trouverez probablement utiles.
La réponse de @Ramana a fonctionné le mieux pour moi, parmi ceux qui sont ici, mais j'ai dû ajouter quelques captures:
import pip
for dist in pip.get_installed_distributions():
if 'site-packages' in dist.location:
try:
pip.call_subprocess(['pip', 'install', '-U', dist.key])
except Exception, exc:
print exc
La vérification site-packages
exclut mes packages de développement, car ils ne se trouvent pas dans le répertoire system-packages du système. Try-except ignore simplement les paquets qui ont été supprimés de PyPI.
@endolith: J'espérais aussi un pip.install(dist.key, upgrade=True)
facile, mais il ne semble pas que pip soit destiné à être utilisé par autre chose que la ligne de commande (la documentation ne mentionne pas l'API interne et les développeurs de pip ne utiliser docstrings).
Envoyé par une demande de tirage au pip folk ; en attendant, utilisez cette solution de bibliothèque de pip, j'ai écrit:
from pip import get_installed_distributions
from pip.commands import install
install_cmd = install.InstallCommand()
options, args = install_cmd.parse_args([package.project_name
for package in
get_installed_distributions()])
options.upgrade = True
install_cmd.run(options, args) # Chuck this in a try/except and print as wanted
Cela semblait fonctionner pour moi ...
pip install -U $(pip list --outdated|awk '{printf $1" "}')
J'ai utilisé printf
avec un espace après pour séparer correctement les noms de paquets.
utiliser les mises à jour de awk:
pip install -U $(pip freeze | awk -F'[=]' '{print $1}')
mise à jour de windows powershell
foreach($p in $(pip freeze)){ pip install -U $p.Split("=")[0]}
Mon script:
pip list --outdated --format=legacy | cut -d ' ' -f1 | xargs -n1 pip install --upgrade
Le plus court et le plus facile sur Windows.
pip freeze > requirements.txt && pip install --upgrade -r requirements.txt && rm requirements.txt
N'est-ce pas plus efficace?
pip3 list -o | grep -v -i warning | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U
pip list -o
liste les paquets périmés;grep -v -i warning
correspondance inversée sur warning
pour éviter les erreurs lors de la mise à jourcut -f1 -d1' '
renvoie le premier mot - le nom du package obsolète;tr "\n|\r" " "
convertit le résultat multiligne de cut
en une liste simple ligne séparée par des espaces;awk '{if(NR>=3)print}'
ignore les lignes d'en-tête cut -d' ' -f1
va chercher la première colonnexargs -n1 pip install -U
prend 1 argument dans le tube à gauche et le transmet à la commande pour mettre à jour la liste des packages.Le pip_upgrade_outdated
fait le travail. Selon ses docs :
usage: pip_upgrade_outdated [-h] [-3 | -2 | --pip_cmd PIP_CMD]
[--serial | --parallel] [--dry_run] [--verbose]
[--version]
Upgrade outdated python packages with pip.
optional arguments:
-h, --help show this help message and exit
-3 use pip3
-2 use pip2
--pip_cmd PIP_CMD use PIP_CMD (default pip)
--serial, -s upgrade in serial (default)
--parallel, -p upgrade in parallel
--dry_run, -n get list, but don't upgrade
--verbose, -v may be specified multiple times
--version show program's version number and exit
Étape 1:
pip install pip-upgrade-outdated
Étape 2:
pip_upgrade_outdated
import pip
pkgs = [p.key for p in pip.get_installed_distributions()]
for pkg in pkgs:
pip.main(['install', '--upgrade', pkg])
ou même:
import pip
commands = ['install', '--upgrade']
pkgs = commands.extend([p.key for p in pip.get_installed_distributions()])
pip.main(commands)
Fonctionne rapidement car il ne lance pas constamment un shell. J'aimerais trouver le temps d'obtenir cette information en utilisant la liste périmée pour accélérer encore les choses.
une ligne dans powershell 5.1 avec les droits adm, python 3.6.5 et pip ver 10.0.1:
pip list -o --format json | ConvertFrom-Json | foreach {pip install $_.name -U --no-warn-script-location}
cela fonctionne bien s'il n'y a pas de paquets cassés ou de roues spéciales dans la liste ...
Que diriez-vous:
pip install -r <(pip freeze) --upgrade
J'ai essayé le code de Ramana et j'ai découvert sur Ubuntu que vous devez écrire Sudo
pour chaque commande. Voici mon script qui fonctionne bien sur Ubuntu 13.10:
#!/usr/bin/env python
import pip
from subprocess import call
for dist in pip.get_installed_distributions():
call("Sudo pip install --upgrade " + dist.project_name, Shell=True)
Je me sers de pur récemment. C'est simple et précis. Il met à jour votre fichier requirements.txt
pour refléter les mises à niveau et vous pouvez ensuite effectuer la mise à niveau avec votre fichier requirements.txt
comme d'habitude.
$ pip install pur
...
Successfully installed pur-4.0.1
$ pur
Updated boto3: 1.4.2 -> 1.4.4
Updated Django: 1.10.4 -> 1.10.5
Updated Django-bootstrap3: 7.1.0 -> 8.1.0
All requirements up-to-date.
$ pip install --upgrade -r requirements.txt
Successfully installed Django-1.10.5 ...
Voici un script qui ne met à jour que les paquets obsolètes.
import os, sys
from subprocess import check_output, call
file = check_output(["pip.exe", "list", "--outdated", "--format=legacy"])
line = str(file).split()
for distro in line[::6]:
call("pip install --upgrade " + distro, Shell=True)
Pour la nouvelle version, pip ne génère pas le format hérité (version 18+).
import os, sys
from subprocess import check_output, call
file = check_output(["pip.exe", "list", "-o", "--format=json"])
line = str(file).split()
for distro in line[1::8]:
distro = str(distro).strip('"\",')
call("pip install --upgrade " + distro, Shell=True)
Voir tous les forfaits obsolètes
pip list --outdated --format=columns
Installer
Sudo pip install pipdate
puis tapez
Sudo -H pipdate
Voici ma variante de la réponse de rbp, qui contourne les distributions "éditable" et de développement. Il partage deux défauts de l'original: il télécharge et réinstalle inutilement; et une erreur sur un paquet empêchera la mise à jour de chaque paquet par la suite.
pip freeze |sed -ne 's/==.*//p' |xargs pip install -U --
Rapports de bugs associés, un peu décousus après la migration de bitbucket:
voici une autre façon de faire avec un script en python
import pip, tempfile, contextlib
with tempfile.TemporaryFile('w+') as temp:
with contextlib.redirect_stdout(temp):
pip.main(['list','-o'])
temp.seek(0)
for line in temp:
pk = line.split()[0]
print('--> updating',pk,'<--')
pip.main(['install','-U',pk])
Voici une solution PowerShell pour Python 3:
pip3 list --outdated --format=legacy | ForEach { pip3 install -U $_.split(" ")[0] }
Et pour Python 2:
pip2 list --outdated --format=legacy | ForEach { pip2 install -U $_.split(" ")[0] }
Ceci met à jour les paquets un par un. Donc un
pip3 check
pip2 check
ensuite, assurez-vous qu'aucune dépendance n'est brisée.
Une ligne en cmd:
for /F "delims= " %i in ('pip list --outdated --format=legacy') do pip install -U %i
Donc un
pip check
ensuite, assurez-vous qu'aucune dépendance n'est brisée.
Et encore une autre manière: for pkg in $(pip list | cut -d' ' -f1); do Sudo pip install --upgrade $pkg; done
import os
import pip
from subprocess import call, check_call
pip_check_list = ['pip', 'pip3']
pip_list = []
FNULL = open(os.devnull, 'w')
for s_pip in pip_check_list:
try:
check_call([s_pip, '-h'], stdout=FNULL)
pip_list.append(s_pip)
except FileNotFoundError:
pass
for dist in pip.get_installed_distributions():
for pip in pip_list:
call("{0} install --upgrade ".format(pip) + dist.project_name, Shell=True)
J'ai pris la réponse de @ Ramana et je l'ai rendu sympathique pour pip3.
Comme une autre réponse ici dit:
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
Une solution possible, Certains commentaires, y compris moi-même, avaient des problèmes d’autorisations lors de l’utilisation de cette commande. Un petit changement à ce qui suit a résolu ceux-ci pour moi.
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 Sudo -H pip install -U
Notez l'ajout de Sudo -H, qui permettait à la commande de communiquer avec les autorisations root.
Voici ma variante:
pip list --outdated --format=legacy | awk '{print $1;}' | xargs -n1 pip install -U
pip list -o | cut -d' ' -f1 | xargs -n1 pip install -U 2> /dev/null
si vous avez 2 versions différentes de python et que vous voulez seulement mettre à jour le paquet de python3, tapez simplement pip3
au lieu de pip
.
Le 2> /dev/null
sert à supprimer tous les messages d'erreur gênants
Le plus court et le plus facile que je puisse trouver:
pip install -U $(pip freeze | cut -d"=" -f1)
La touche $(cmd)
vous permet d’envelopper toute ligne de commande Shell (elle renvoie sa sortie).
Pur bash/zsh oneliner pour le faire:
for p in $(pip list -o --format freeze); do pip install -U ${p%%=*}; done
Ou, au format Nice:
for p in $(pip list -o --format freeze)
do
pip install -U ${p%%=*}
done
Voici un moyen rapide de mettre à jour tous les packages installés:
for pkg in $(pip list | cut -d' ' -f1) ; do pip install $pkg -U ; done
python -c 'import pip; [pip.main(["install", "--upgrade", d.project_name]) for d in pip.get_installed_distributions()]'
Bon mot!
Si vous voulez mettre à niveau uniquement les paquets installés par pip et éviter de mettre à jour les paquets installés par d'autres outils (comme apt, yum etc.), vous pouvez utiliser ce script que j'utilise sur mon Ubuntu (peut aussi fonctionner sur d'autres distributions) - basé sur ce post :
printf "To update with pip: pip install -U"
pip list --outdated 2>/dev/null | gawk '{print $1;}' | while read; do pip show "${REPLY}" 2>/dev/null | grep 'Location: /usr/local/lib/python2.7/dist-packages' >/dev/null; if (( $? == 0 )); then printf " ${REPLY}"; fi; done; echo
installez jq en premier (mac):
$ brew installer jq
2.
$pip3 install --upgrade `pip3 list --outdated --format json | jq '.[] | .name' | awk -F'"' '{print $2}'`
Il suffit d'ajouter une réponse JSON + JQ pour les enregistrements:
pip list -o --format json | jq '.[] | .name' | xargs pip install -U
la meilleure solution qui fonctionne même en conda env est:
pip freeze --local | grep -v '^\-e' | cut -d = -f 1 |cut -d ':' -f 2 | xargs -n1 pip install -U
L'extrait cmd
ci-dessous effectue les opérations suivantes:
- Mises à niveau
pip
vers la dernière version.- Met à jour tous les paquets obsolètes.
- Pour chaque paquet en cours de mise à niveau, vérifie
requirements.txt
pour tout spécificateur de version.
@echo off
Setlocal EnableDelayedExpansion
rem https://stackoverflow.com/questions/2720014
echo Upgrading pip...
python -m pip install --upgrade pip
echo.
echo Upgrading packages...
set upgrade_count=0
pip list --outdated > pip-upgrade-outdated.txt
for /F "skip=2 delims= " %%i in (pip-upgrade-outdated.txt) do (
echo ^>%%i
set package=%%i
set requirements=!package!
rem for each outdated package check for any version requirements
for /F %%r in (.\python\requirements.txt) do (
call :substr "%%r" !package! _substr
rem check if a given line refers to a package we are about to upgrade
if "%%r" NEQ !_substr! (
rem check if the line contains more than just a package name
if "%%r" NEQ "!package!" (
rem set requirements to what is contained in this line
echo requirements: %%r
set requirements=%%r
)
)
)
pip install --upgrade !requirements!
set /a "upgrade_count+=1"
echo.
)
if !upgrade_count!==0 (
echo All packages are up to date.
) else (
type pip-upgrade-outdated.txt
)
exit /b
:substr
rem string substition done in a separate subroutine -
rem allows expand both variables in the substring syntax
set str_source=%1
set str_search=%2
rem replace str_search with an empty string.
rem return the result in the 3rd parameter, passed by reference from the caller.
set "%~3=!str_source:%str_search%=!"
exit /b