web-dev-qa-db-fra.com

Mise à jour de tous les paquets avec pip

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.

1588
thedjpetersen

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

1818
rbp

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)
573
Ramana

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 .

545
jfs

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.

216
azazelspeaks

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
99
Piotr Dobrogost

Vous pouvez simplement imprimer les paquets périmés

pip freeze | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'
70
janrito

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
58
raratiru

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.

51
Marc

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

35
Shihao Xu

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.

  • Problèmes de portabilité dus à la modification des fonctionnalités de ligne de commande pip
  • Crashing de xargs en raison d'échecs courants du processus enfant pip ou pip3
  • Journalisation surchargée à partir de la sortie de xargs brute
  • S'appuyant sur un pont Python vers OS tout en le mettant potentiellement à niveau3

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.

28
Douglas Daseeco

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.

27
Simion Agavriloaei

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
26
tkr

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()]'

`

24
Salman Abbas

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
16
brunobord

Utilisez pipupgrade !

$ 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 +.

 enter image description here

NOTE: je suis l'auteur de l'outil.

15

Solution Windows Powershell

pip freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}
15
Apeirogon Prime

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

Source: https://github.com/pypa/pip/issues/3819

13
RedEyed

Vous pouvez essayer ceci:

for i in ` pip list|awk -F ' ' '{print $1}'`;do pip install --upgrade $i;done
12
何宗翰

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.

12
user1175849

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

10
chbrown

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
9
Samuel Marks

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.

9
SaxDaddy

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

8
JohnDHH

Mon script:

pip list --outdated --format=legacy | cut -d ' ' -f1 | xargs -n1 pip install --upgrade
6
Icyblade

Le plus court et le plus facile sur Windows.

pip freeze > requirements.txt && pip install --upgrade -r requirements.txt && rm requirements.txt
6
Ankireddy

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 
  1. pip list -o liste les paquets périmés;
  2. grep -v -i warning correspondance inversée sur warning pour éviter les erreurs lors de la mise à jour
  3. cut -f1 -d1' ' renvoie le premier mot - le nom du package obsolète;
  4. tr "\n|\r" " " convertit le résultat multiligne de cut en une liste simple ligne séparée par des espaces;
  5. awk '{if(NR>=3)print}' ignore les lignes d'en-tête 
  6. cut -d' ' -f1 va chercher la première colonne
  7. xargs -n1 pip install -U prend 1 argument dans le tube à gauche et le transmet à la commande pour mettre à jour la liste des packages.
6
Alex V

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
5
adrin
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.

5
Steve Barnes

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 ...

5

Que diriez-vous:

pip install -r <(pip freeze) --upgrade
5
user8598996

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)
4
antibus

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 ...
4
kichik

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)
4
Storm Shadow

Voir tous les forfaits obsolètes

 pip list --outdated --format=columns

Installer

 Sudo pip install pipdate

puis tapez

 Sudo -H pipdate
4
Usman khan

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:

4
Tobu

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])
4
Copperfield

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.

4
Nils Ballmann

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.

2
Ilya

Et encore une autre manière: for pkg in $(pip list | cut -d' ' -f1); do Sudo pip install --upgrade $pkg; done

2
user1529891
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.

2
Mo Ali

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. 

2
thebeancounter

Voici ma variante:

pip list --outdated --format=legacy | awk '{print $1;}' | xargs -n1 pip install -U
2
Jaime Arias
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 

1
AkaKaras

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

1
Alexandre Huat

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
1
German Lashevich

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
0
Riccardo M.
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
0
keypress
  1. installez jq en premier (mac):

    $ brew installer jq

2.

$pip3 install --upgrade  `pip3 list --outdated --format json | jq '.[] | .name' | awk -F'"' '{print $2}'`
0
Cando Zhou

Il suffit d'ajouter une réponse JSON + JQ pour les enregistrements:

pip list -o --format json | jq '.[] | .name' | xargs pip install -U
0
Alex

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
0
ermiabivatan

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
0
Andy