Pip: Ajouter les commandes « upgrade » et « upgrade-all »

Créé le 15 mars 2011  ·  251Commentaires  ·  Source: pypa/pip

(Mise à jour pour refléter la réalité en avril 2020)

Ce problème visait initialement à modifier le comportement de pip install --upgrade , en ajoutant une nouvelle commande upgrade avec un comportement différent lors de la mise à niveau des packages. L'ancienne valeur par défaut « avide » récursive a causé du chagrin à beaucoup (#304). Cependant, après de nombreuses discussions à ce sujet, l'approche adoptée a été d'ajouter le drapeau --upgrade-strategy . Le drapeau avait initialement une valeur par défaut de « eager » qui a été remplacée par une meilleure valeur par défaut dans #4500.

Le problème de suivi pour la fonctionnalité "Mettre à niveau tous les packages" est le n° 4551.

upgrade auto-locked enhancement

Commentaire le plus utile

Allez-vous mettre cela en œuvre dans les 10 prochaines années ?

Tous les 251 commentaires

"upgrade" est un alias trivial pour "install --upgrade". Besoin de réfléchir un peu plus
à propos de "mettre à niveau tout" ; d'une part, je suppose que cela ne ferait que mettre à niveau les packages
à l'intérieur de sys.prefix ? (c'est-à-dire si vous êtes à l'intérieur d'un virtualenv, il n'essaierait pas de
mise à niveau des packages globaux). Ce serait une raison pour déménager
UninstallPathSet.can_uninstall() vers une fonction plus générique (ou
méthode de InstallRequirement), il fournit donc un générique « puis-je toucher à ça ? »
les décisions.


Original Comment By: Carl Meyer

Pour mémoire, je pense que cela semble être une bonne idée, étant donné la capacité de
désinstaller avant la mise à niveau. Bien que je préfère une option --all pour
upgrade au lieu d'une propre commande upgrade-all .

Pour ce qui est de can_uninstall(), je suis d'accord.. c'est probablement pratique à avoir
globalement en tout cas.


Original Comment By: Jannis Leidel

Je ne suis pas totalement opposé à la mise à niveau en tant qu'alias pour install --upgrade. Mais
cela semble un peu banal.

upgrade-all vous oblige à déterminer ce qui est « évolutif ». Probablement un
la condition préalable est qu'il habite/lib/pythonX.Y/site-packages
(simplement sous sys.prefix ne suffit pas).

Si nous autorisons quelque chose comme « zip import » (pour apporter un paquet du parent
environnement dans un environnement virtualenv) puis probablement des packages dans cet
l'environnement parent ne devrait pas être mis à niveau, mais ce n'est pas clair à 100%
l'utilisateur attendra.

J'ai essayé de désinstaller un package modifiable avec "pip uninstall" et c'est assez
raisonnablement proposé de supprimer le lien .egg et de mettre à jour easy-install.pth. Mais il
n'aurait pas pu raisonnablement mettre à niveau le package, donc can_uninstall est quelque peu
différent de can_upgrade.


Original Comment By: Ian Bicking

Oui, vous avez raison, can_uninstall et can_upgrade sont différents.

Je pense que si nous avions "l'importation de pip", nous ne voudrions toujours pas mettre à niveau
packages globaux importés ; mais (avec les modifiables) cela pourrait valoir un "pas
mise à niveau de cet" avertissement sur la console.


Original Comment By: Carl Meyer

+1 pour ce bug


Original Comment By: smyrman

Le problème #167 a été marqué comme un doublon de ce problème.


Original Comment By: Carl Meyer

1

(echo pip; pip freeze | awk 'BEGIN{FS="=="}{print $1}') | xargs sudo pip

installer -U

Cela devrait mettre à niveau tous les packages installés (y compris pip lui-même). Si
vous l'exécutez dans virtualenv, vous n'avez probablement pas besoin d'utiliser sudo.

Bien sûr, il y a un risque élevé d'échec - si vous mettez à niveau l'un des packages
échoue tout le processus échouera (c'est similaire à port upgrade outdated dans
MacPorts).


Original Comment By: Tomasz Elendt

+1 pour la mise à niveau --all

Pourquoi à l'heure actuelle toutes les installations de gestion de modules Python doivent-elles être nulles ? Pourquoi non
l'un fournit une simple commande upgrade + upgrade --all ?


Original Comment By: Anonymous

Cela ne me dérangerait pas de tenter une implémentation, mais d'abord quelques questions.

Le consensus général est-il qu'une nouvelle commande "upgrade" qui prend en charge un "--all"
option être ajoutée à pip?

L'exécution de la mise à niveau de pip ne devrait affecter que l'environnement dans lequel il s'exécute. Si
exécuté à partir d'un environnement virtuel, seuls les packages locaux vers cet environnement seront mis à niveau ;
idem pour les non-virtualenv


Original Comment By: Kelsey Hightower

Kelsey : d'après ma lecture de la discussion ci-dessus, je ne vois pas de réel
s'y opposer. Je pense que c'est un bon ajout à faire. Le cas de bord principal est
installations VCS modifiables - comme Ian l'a suggéré, je pense qu'une commande "mise à niveau"
ne devrait pas toucher ceux-ci. Définir ce que signifie « mise à niveau » dans le contexte de tous les
possibilités modifiables (y compris les repos locaux installés modifiables qui n'ont pas
origine) serait presque impossible, je pense, et même si certains travaillaient à mi-chemin
définition pourrait être élaborée, cela ne ferait qu'augmenter la maintenance
fardeau des backends VCS déjà fragiles. Mais pour les non modifiables, optez pour
ce!


Original Comment By: Carl Meyer

Carl : Cool, je vais commencer et mettre à jour ce ticket avec les résultats.


Original Comment By: Kelsey Hightower

En travaillant sur la commande de mise à niveau, les questions suivantes se sont posées :

  • Quelles méthodes devraient prendre en charge la mise à
    améliorer? Doit-on supporter un fichier d'exigences ?
  • Comment pip upgrade doit-il gérer les packages qui ne sont pas déjà installés ?
    Doit-on installer les packages manquants ?
cas d'utilisation de la mise à niveau de pip et comment les gérer :
# pip upgrade some_installed_package

Try and locate a package that satisfies the requirement. If the

l'exigence n'est pas satisfaite mise à niveau vers la version demandée. Ceci comprend
mise à niveau vers une ancienne version.

# pip upgrade --all

Locate all installed packages (non-editables) and update them to a new

version si disponible.

# pip upgrade some_other_package

Warning: some_other_package not installed, use pip install

some_other_package.

Mes objectifs sont de garder la commande de mise à niveau vraiment simple. Vous pouvez mettre à niveau
des packages spécifiques non modifiables vers une nouvelle ou une ancienne version ; ou vous pouvez mettre à niveau
tous les packages non modifiables vers une version plus récente.

Les pensées?


Original Comment By: Kelsey Hightower

Je pense que "pip upgrade" devrait être un alias exact pour "pip install --upgrade" comme
ça fonctionne maintenant. Cela implique que oui, il installe les packages demandés s'ils
ne sont pas installés, et oui, il accepte les fichiers d'exigences avec -r. Son devrait
être faisable avec presque aucun nouveau code.

Upgrade --all nécessitera du code pour trouver la liste des
packages évolutifs installés ; alors il devrait juste passer cette liste à installer
--upgrade, comme ci-dessus.


Original Comment By: Carl Meyer

Carl, merci pour la réponse. J'ai à peu près pris le chemin que vous avez
décrit. Plus tard dans la journée, je devrais être en mesure de publier quelques exemples de courses.


Original Comment By: Kelsey Hightower

J'ai fait la plupart du code, il me reste juste un peu de polissage avant de poster le code
pour évaluation.

FAIRE:

  • Essais
  • Filtrer le fichier des exigences ; ajouter des éléments non modifiables à la liste des packages à
    améliorer.
Exécution de pip à l'aide de la commande upgrade
# pip upgrade --all

All packages up-to-date


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

All packages up-to-date


# pip upgrade PyYAML

Package updates available:

  PyYAML: N/A (installed) 3.09 (latest)

Downloading/unpacking PyYAML

  Downloading PyYAML-3.09.tar.gz (238Kb): 238Kb downloaded

....

Successfully installed PyYAML

Cleaning up...


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  PyYAML: 3.09 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

All packages up-to-date


# pip upgrade PyYAML==3.08

Downloading/unpacking PyYAML==3.08

....

Successfully installed PyYAML

Cleaning up...


# pip upgrade --all -v

Packages installed at latest version:

  pip: 0.8.2 (latest)

  distribute: 0.6.14 (latest)

  Python: 2.7.1 (latest)

  wsgiref: 0.1.2 (latest)

Package updates available:

  PyYAML: 3.08 (installed) 3.09 (latest)

Downloading/unpacking PyYAML

...

Successfully installed PyYAML

Cleaning up...

  Removing temporary dir /root/upgrade_env/build...

Original Comment By: Kelsey Hightower

Dernière série de questions (j'espère) :

  • La mise à niveau de pip doit-elle analyser le fichier d'exigences et filtrer
    modifiables ? Qu'en est-il des exigences d'URL ?

Pour chaque élément non modifiable du fichier d'exigences, je voudrais vérifier le
index pour une version ultérieure. Pour ce faire, j'aurais besoin de rassembler les
informations sur le package à partir de chaque ligne du fichier d'exigences.

Tous les conseils sont les bienvenus (en train de regarder pip.req.parse_requirements )

  • La mise à niveau de pip doit-elle rechercher dans les index une version ultérieure à installer ?
    (C'est ce que je fais maintenant). Sinon, comment la commande de mise à niveau doit-elle déterminer
    s'il y a une mise à jour ?

Pour le moment, je n'ajoute des packages à la liste de mise à niveau que lorsque :

  • Le paquet n'est pas installé
  • Une mise à jour est disponible (version ultérieure à partir des index), et aucune
    la version a été demandée
  • La version demandée est différente de celle installée (Version miss
    correspondre).
  • Je reporte le fichier d'exigences à la commande d'installation jusqu'à ce que je filtre
    les exigences non modifiables.

Original Comment By: Kelsey Hightower

Carl après avoir relu votre message, il semble que je fasse plus que ce qui est
obligatoire. Je vais télécharger ma branche pour que vous puissiez y jeter un œil. je suis peut-être allé
par dessus bord en vérifiant PyPi pour une version ultérieure.


Original Comment By: Kelsey Hightower

Carl après avoir relu votre message, il semble que je fasse plus que ce qui est
obligatoire. Je vais télécharger ma branche pour que vous puissiez y jeter un œil. je suis peut-être allé
par dessus bord en vérifiant PyPi pour une version ultérieure.


Original Comment By: Kelsey Hightower

Oui, on dirait que vous faites plus que ce qui devrait être nécessaire. Pip installer
--upgrade fait déjà tout ce dont vous discutez (vérification des
versions, etc.); toute "mise à niveau de pip" devrait être comme un passage à deux lignes
tout est terminé pour pip install --upgrade.

Le seul vrai code à écrire ici est le code pour "upgrade --all" pour obtenir
la liste complète des packages évolutifs installés dans l'environnement.


Original Comment By: Carl Meyer

Ouais, je le savais. Eh bien, j'ai beaucoup appris. Même si ce n'est pas nécessaire pour cela
tâche, j'aime la possibilité de montrer ce qui est installé et disponible pendant la
processus de mise à niveau (voir le test ci-dessus).

Je vais re-factoriser et nettoyer les choses. Changements actuels dans ma fourche sur le
branche de commande de mise à niveau.

https://bitbucket.org/khightower/pip/changeset/2bdc202b446c


Original Comment By: Kelsey Hightower

J'ai supprimé la commande de mise à niveau selon les suggestions de Carl (je suis allé trop loin
en premier lieu). Je ne suis pas sûr d'aimer les résultats, mais il s'installe en miroir--mise à niveau des fonctionnalités.

Il semble que pip essaie de télécharger et de réinstaller le package même lorsque le
package est déjà installé et à jour. Encore pire avec la mise à

la mise à niveau devrait fonctionner ? Si c'est le cas, j'ai presque fini :)

Exécution de la commande de mise à niveau pip
# pip upgrade Mako


Downloading/unpacking Mako

  Running setup.py egg_info for package Mako


    warning: no files found matching '*.jpg' under directory 'doc'

    warning: no files found matching '*.sty' under directory 'doc'

    warning: no files found matching 'autohandler' under directory 'doc'

    warning: no files found matching '*.xml' under directory 'examples'

    warning: no files found matching '*.mako' under directory 'examples'

    warning: no files found matching '*.dat' under directory 'test'

    warning: no files found matching 'ez_setup.py'

Downloading/unpacking MarkupSafe>=0.9.2 (from Mako)

  Running setup.py egg_info for package MarkupSafe


Installing collected packages: Mako, MarkupSafe

  Found existing installation: Mako 0.3.6

    Uninstalling Mako:

      Successfully uninstalled Mako

  Running setup.py install for Mako

    changing mode of build/scripts-2.7/mako-render from 644 to 755


    warning: no files found matching '*.jpg' under directory 'doc'

    warning: no files found matching '*.sty' under directory 'doc'

    warning: no files found matching 'autohandler' under directory 'doc'

    warning: no files found matching '*.xml' under directory 'examples'

    warning: no files found matching '*.mako' under directory 'examples'

    warning: no files found matching '*.dat' under directory 'test'

    warning: no files found matching 'ez_setup.py'

    changing mode of /root/upgrade_env/bin/mako-render to 755

  Found existing installation: MarkupSafe 0.11

    Uninstalling MarkupSafe:

      Successfully uninstalled MarkupSafe

  Running setup.py install for MarkupSafe


    building 'markupsafe._speedups' extension

    gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall

-Wstrict-prototypes -fPIC -I/opt/OpenPython-2.7.1/include/python2.7 -c
markupsafe/_speedups.c -o build/temp.linux-x86_64-2.7/markupsafe/_speedups.o

    gcc -pthread -shared

build/temp.linux-x86_64-2.7/markupsafe/_speedups.o -o
build/lib.linux-x86_64-2.7/markupsafe/_speedups.so

Successfully installed Mako MarkupSafe

Cleaning up...

Original Comment By: Kelsey Hightower

Kelsey - Oui, il y a quelques bogues avec install --upgrade ; en particulier vous
identifié #13 , qu'il télécharge et réinstalle même les packages qui
sont déjà à jour. La solution n'est pas de faire quelque chose de différent
avec la nouvelle commande de mise à niveau, il s'agit de corriger le bogue dans install --upgrade.

Avec upgrade --all, il me semble raisonnable que pip se mette à jour
aussi, s'il y a une mise à niveau disponible. (Personnellement je n'utiliserai jamais la mise à niveau
--all, donc je ne sais pas quel comportement les gens qui l'utiliseront en attendraient
ici). De toute évidence, encore une fois, il vaudrait mieux se comporter si le numéro 13 était corrigé.


Original Comment By: Carl Meyer

Merci Carl, je vais conclure et commencer à regarder #13


Original Comment By: Kelsey Hightower

Si quelqu'un a le temps, veuillez consulter ma branche de commande de mise à niveau. Pendant ce temps
Je vais travailler sur des unittests qui essaient de ne pas dupliquer ceux existants pour le
commande d'installation.

https://bitbucket.org/khightower/pip/src/fa7b2a6d2bf1/pip/commands/upgrade.py


Original Comment By: Kelsey Hightower

@vababiy : j'ai essayé votre commande de mise à niveau, mais elle semble ne pas fonctionner correctement... J'en ai donc créé une :

https://github.com/pypa/pip/pull/313
https://github.com/jedie/pip/commit/7a31d70dabe0e809184fe1b5280c5a7ccf420dd5

@jedie, je pense que vous vouliez adresser votre commentaire à @khightower. @vbabiy a migré son commentaire ici mais n'a pas écrit la commande de mise à niveau.

+1

@kelseyhightower Des progrès ?

+1

+1 !

+1

+1

S'il vous plaît arrêtez de commenter le problème avec juste un "+1". Nous sommes conscients que la fonctionnalité est recherchée, mais le spam dans notre boîte de réception n'aide pas.

Au lieu de cela, je serais ravi de voir un commentaire "patch done!" ;)

+1

Les mises à jour? Est-il prévu d'ajouter ceci, il a 3 ans maintenant..

+1

Je pensais que c'était déjà fusionné. Je peux dépoussiérer mes compétences en python et réessayer.

Cette fonctionnalité sera-t-elle incluse dans 1.5 ? Je ne trouve aucune référence à cela dans la documentation 1.5...

+1

Quel est le statut de cette question?

Il est bloqué par #988

Si c'est vraiment important pour vous, il existe des solutions de contournement pour mettre à niveau tous les packages ; J'ai créé un script pour le faire en parallèle (https://github.com/ariccio/update-pip-packages), et il existe de nombreuses autres implémentations ailleurs sur Internet.

Il y a deux parties à cette question. upgrade-all peut être bloqué par gh-988, mais je ne vois pas comment upgrade est bloqué. pip upgrade peut être un simple alias pour pip install -U --no-deps . Cela résoudrait l'un des principaux problèmes liés à l'utilisation de install_requires dans les fichiers setup.py. Cela ne peut-il pas être fait bientôt?

pip upgrade peut être un simple alias pour pip install -U --no-deps

d'après le descriptif :

pip upgrade serait comme pip install --upgrade sauf qu'il serait non récursif par défaut (et offrirait une option --recursive ). Son comportement par défaut récursif actuel a causé du chagrin à beaucoup (#304). Quant à savoir comment faire des mises à niveau non récursives maintenant, voir ici

ce n'est pas pip install -U --no-deps

« non récursif » dans ce contexte ne signifie pas simplement –no-deps . Une mise à niveau non récursive mettra à niveau les dépendances, mais uniquement si cela est nécessaire pour répondre aux exigences des parents.

@qwcode merci pour la clarification. Alors ce n'est pas ce qui m'importe. Pourquoi appelleriez-vous cela "non récursif", c'est toujours récursif mais juste un peu plus intelligent/différent ?

J'avais l'impression d'après la discussion dans gh-571 que vraiment non récursif était la valeur par défaut souhaitée. Cela aurait certainement du sens et éviterait d'avoir à toujours écrire du code comme https://github.com/scipy/scipy/commit/8e7ee0c4b3c16.

dans #571, "non récursif" n'est pas --no-deps c'est le récursif "plus intelligent/différent" comme vous le dites.
notez le test test_upgrade_with_needed_recursive_upgrades() de ce PR.

sans se coincer dans les termes, il y a 3 choses :

  1. la "mise à niveau plus intelligente/différente", c'est-à-dire le type qui se produit dans l'emballage du système d'exploitation qui peut également impliquer des dépendances de mise à niveau (mais seulement si elles ont réellement besoin d'une mise à niveau).
  2. ce que pip fait maintenant, qui est de mettre à niveau toutes les dépendances, indépendamment des besoins ou de la résolution des conflits.
  3. --no-deps

quelques façons possibles de distinguer #1 et #2

  1. "non récursif" vs "récursif"
  2. "normal" vs "récursif"
  3. "seulement si nécessaire récursif" vs "faites-le indépendamment de la récursivité"

Je suis ouvert à l'utilisation des meilleurs termes... je ne suis pas sûr de ce que c'est.

Je pense que j'aime cette phrase "récursive uniquement si nécessaire". peut-être que je devrais l'utiliser ici dans la doc :

J'aime ça aussi. Si vous décrivez les trois options ensemble comme

a. non-recursive
b. only if needed recursive
c. recursive (or "do it regardless recursive")

ce serait clair.

Ensuite, vous voulez choisir de bonnes valeurs par défaut. Pour upgrade et install -U , (a) ou (b) pourrait avoir un sens. Je préfère fortement (a), mais (b) est également logique étant donné que c'est ce que fait l'emballage du système d'exploitation.

(c) n'a aucun sens par défaut, veuillez donc reconsidérer votre décision de ne pas modifier install -U .

Pour clarifier pourquoi je préfère fortement (a) : un utilisateur sans méfiance voulant (b) et obtenant (a) devra lire un message disant "non-recursive upgrade can't satisfy all dependencies, please use only-if-needed recursive" , ce qui n'est pas si grave. Si la valeur par défaut était (b), cet utilisateur sans méfiance pourrait se retrouver avec une mise à niveau ou même une installation interrompue d'un paquet qu'il ne voulait vraiment pas toucher. Cela peut prendre des heures, voire des jours, pour s'en remettre.

(c) n'a aucun sens par défaut, veuillez donc reconsidérer votre décision de ne pas modifier install -U

la raison de laisser install -U seul est juste pour des raisons de compatibilité, puis de le déprécier éventuellement.

Si la valeur par défaut est (b), cet utilisateur sans méfiance peut se retrouver avec une mise à niveau
ou même une installation cassée d'un paquet qu'il ne voulait vraiment pas toucher

si un utilisateur souhaite que les mises à niveau de dépendances nécessaires ne soient pas effectuées, il doit spécifiquement les demander en utilisant --no-deps . il n'y a aucun moyen dans mon esprit qui pourrait jamais être la valeur par défaut. ce comportement ferait plus de dégâts que ce que vous envisagez (ce qui est le cas aberrant). À maintes reprises, les utilisateurs se retrouveraient sans les mises à niveau de dépendance dont ils avaient besoin.

Déprécier install -U ça sonne bien.

Je suis d'accord que (b) est plus courant que (a). Même si ce serait 100 fois plus fréquent, ce qui n'est pas le cas je pense, plus de dégâts sont faux. Lire un message d'erreur clair avant le début de l'installation est tellement mieux que, par exemple, une erreur de compilation à mi-chemin, que mon humble avis (a) est toujours la meilleure valeur par défaut.

S'appuyer sur --no-deps peut convenir aux utilisateurs très expérimentés, mais les nouveaux utilisateurs ne l'apprendront qu'une fois que les choses auront mal tourné.

Quoi qu'il en soit, il semble que je ne pourrai pas vous convaincre. Puis retour au manuel

try:
   import dependency
except ImportError:
    install_requires.append('dependency')
else:
    if dependency.version < 'x.y.z':
        raise ValueError('Please upgrade dependency to x.y.z')

il est.

@qwcode merci pour l'explication détaillée. J'espère que cela avancera dans un proche avenir - seulement si nécessaire, la récursivité serait une énorme amélioration par rapport au comportement actuel.

Passant à nouveau de nombreuses heures cette semaine à résoudre des problèmes sur les raisons pour lesquelles nous n'utilisons pas install_requires , j'ajoute un :+1: pour m'éloigner du comportement actuel.

Y a-t-il des mises à jour sur ce problème?

Nous avons maintenant 2015 et j'ai encore besoin de copier à partir de pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U stackoverflow

Oui, essentiellement tous les progrès sont liés à ce problème.

pip_upgrade_github

GitHub fait un très bon travail de références croisées. Tous sont cliquables ! (Je suis sûr que vous le savez ?)

Oui, bien sûr, mais je ne comprends pas pourquoi cette fonctionnalité "simple" a un tel retard.

Quelle est la raison pour ça?

Suis 16.04.2015 à 05:28 schrieb Alexander Riccio [email protected] :

Oui, essentiellement tous les progrès sont liés à ce problème.

GitHub fait un très bon travail de références croisées. Tous sont cliquables ! (Je suis sûr que vous le savez ?)

-
Répondez directement à cet e-mail ou consultez-le sur GitHub.

quant à pip upgrade-all , le consensus semble être d'attendre le travail lié à #988 avant de publier de nouvelles commandes brillantes qui sont encore en fin de compte imparfaites et peuvent être dangereuses pour un environnement de travail. Une version simple de upgrade-all qui ne résout pas correctement les exigences peut facilement casser les packages existants

+1

Que fais-tu depuis 4 ans ?

+1

+1

+1

@muhasturk Actuellement, en attente... https://github.com/pypa/pip/issues/59#issuecomment -93646462

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1 ...désolé pour le spam, mais courir pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U fait mal !

+1

Au cas où quelqu'un serait intéressé à travailler sur cela, je pense que les commentaires ci-dessus sont quelque peu déroutants -- AFAICT le statut réel est que pip upgrade-all est actuellement bloqué par la nécessité d'un système de résolution de dépendance approprié, mais pip upgrade peut être implémenté à tout moment. Si quelqu'un veut travailler sur cette partie, ce serait extrêmement génial :-).

(Voir aussi le fil commençant ici et la réponse de @dstufft ici et commenter ici en accord avec l'évaluation ci-dessus.)

voici une autre discussion de la liste pypa-dev d'il y a un an (qui confirme que pip upgrade FOO pourrait être fait maintenant) https://groups.google.com/forum/#!searchin/pypa -dev/pip$20 mise à niveau/pypa-dev/vVLmo1PevTg/oBkHCPBLb9YJ

Merci @qwcode ! Je viens également de voir la nouvelle description sur https://pip.pypa.io/en/latest/user_guide/#only -if-needed-recursive-upgrade, c'est utile.

+1

Si je ne me trompe pas:

Si xxx n'est pas installé :

  • pip upgrade xxx équivaudrait à pip install xxx
  • pip upgrade xxx --recursive serait l'équivalent de pip install xxx --upgrade

Si xxx est installé :

  • pip upgrade xxx --recursive serait toujours l'équivalent de pip install xxx --upgrade (par conception)
  • mais il n'y a actuellement pas d'équivalent pour pip upgrade xxx , cela pourrait être pip install xxx --upgrade-only-if-needed/--upgrade-lazy

On ne sait pas quelle est la valeur ajoutée d'une nouvelle commande par rapport à l'ajout d'une nouvelle option à pip install ?

On ne sait pas quelle est la valeur ajoutée d'une nouvelle commande par rapport à l'ajout d'une nouvelle option à pip install ?

Le comportement par défaut de pip install -U est inacceptable pour de nombreux projets. Voir mon commentaire ci-dessus (https://github.com/pypa/pip/issues/59#issuecomment-52434862). Et voici une explication plus longue : http://article.gmane.org/gmane.comp.python.distutils.devel/24218

Si c'est inacceptable, alors je suppose que vous prévoyez de changer votre utilisation de pip install --upgrade to pip upgrade ?
Pourquoi ne pourriez-vous pas à la place changer votre utilisation actuelle de pip install --upgrade en pip install --upgrade-only-needed ?
Qu'est-ce qu'une nouvelle commande fournit qu'une nouvelle option ne pourrait pas ?

Il s'agit de paver les chemins des vaches. Ce n'est pas l'utilisation personnelle de @rgommers qui l'inquiète, ce sont ses utilisateurs. Les gens vont chercher la réponse "évidente" s'ils ne savent pas mieux et en ce moment, la réponse évidente est problématique pour certains éléments majeurs de l'écosystème Python.

En effet. Les gens ne lisent pas les docs. En effet, nous allons corriger toutes les docs d'installation que nous pouvons trouver, mais dès qu'un utilisateur verra -U ou --upgrade c'est ce qu'il utilisera. La chance que les gens utilisent --no-deps ou --only-as-needed ou quoi que ce soit avant d'avoir été sérieusement mordu par cela est faible.

Pourquoi ne pourriez-vous pas à la place changer votre utilisation actuelle de pip install --upgrade en pip install --upgrade-only-needed ?

Et pour être clair : nous évitons pip install --upgrade maintenant _et_ n'utilisons pas install_requires cause de cela. C'est à quel point c'est mauvais.

Je pense qu'il y a un petit malentendu ici - IIUC @xavfernandez est d'accord avec l'ajout de la fonctionnalité de mise à niveau non récursive, leur question est simplement pourquoi l'interface utilisateur de cette fonctionnalité doit être une nouvelle commande de niveau supérieur au lieu d'une nouvelle option pour pip install .

@xavfernandez : Notez qu'il y a actuellement une discussion dans #3194 sur ce qui serait l'interface utilisateur la plus claire pour cette fonctionnalité.

(Et pip install -U sera obsolète puis supprimé, ce qui répond à la question de savoir comment les utilisateurs sauront ne pas l'utiliser :-).)

Je pense qu'il y a un petit malentendu ici

Je suis presque sûr qu'il n'y en a pas. Et oui, nous ne discutons que de l'interface utilisateur. Mais c'est important.

Oui, débattre uniquement de l'interface utilisateur et je suis d'accord que c'est important. Mais ce que je vois venir, c'est qu'une fois la mise à niveau de pip terminée, il n'y aura aucune raison de continuer à utiliser pip install...
Et l'interface utilisateur pour installer n'importe quel paquet deviendra "pip upgrade foo"

il n'y aura aucune raison de continuer à utiliser pip install

qui est un problème pourquoi? Le problème (au moins pour @qwcode dans les commentaires ci-dessus) avec le changement de pip install --upgrade vers le bon comportement rompt la compatibilité descendante. Donc pip upgrade est le moyen d'éviter cette rupture _et_ d'obtenir la bonne valeur par défaut.

@rgommers : pour être juste, nous _aurons_ un nombre non nul de questions confuses sur pourquoi m'avez-vous dit d'exécuter pip upgrade foo alors que je n'ai même pas foo installé, ça n'a pas été le cas ça ne fonctionne pas (se disputer jusqu'à ce qu'ils essaient réellement d'exécuter la commande au lieu de supposer que cela ne fonctionnera pas et de prétendre qu'ils l'ont exécutée)

Sur #3194 j'ai fait le commentaire que peut-être la bonne voie à suivre est de simplement supprimer --upgrade de pip install , faire en sorte que pip install fasse toujours une mise à niveau des éléments explicitement nommés, et par défaut à une stratégie de mise à niveau minimale pour les dépendances avec un indicateur --recursive pour obtenir le comportement actuel lors de la mise à niveau.

Je pense que je suis d'accord avec le fait qu'avec #3194, l'UX par défaut deviendra pip upgrade foo au lieu de pip install [-U] foo . Le seul problème que j'ai avec ça, c'est que je pense que c'est un peu déroutant d'avoir les deux commandes et étant donné que je pense que pip upgrade serait la "bonne" pour les gens à utiliser, je pense que c'est minable d'avoir l'évidence nom soit le mauvais nom.

J'ai une migraine, donc je pourrais aussi ne pas penser tout à fait correctement, mais j'ai en quelque sorte envie de comprendre comment gérer le chemin de la dépréciation vers cette suggestion pourrait être la bonne voie à suivre.

Eh bien, je ne soutiendrai pas que la compatibilité descendante est importante ici. J'ai toujours été en faveur de la modification du comportement de pip install --upgrade . C'est le plus propre, et le coût semble faible. Mais il me semblait que @qwcode y avait opposé son veto, donc pip upgrade était la prochaine meilleure chose (et déjà acceptée par les développeurs de pip il y a un an).

Si nous voulons maintenant revenir à la modification des paramètres par défaut/du comportement de pip install , c'est parfait.

@dstufft qui a tout son sens pour moi - le mal de tête ne peut pas être si grave :)

Puisque nous acceptons de déprécier --upgrade, nous pourrions conserver cela et ajouter deux options à pip install : --upgrade-only-needed et --upgrade-eager , la seconde étant un alias pour le --upgrade obsolète

@xavfernandez Forcer les décisions aux utilisateurs est un peu minable, je pense. À moins que je ne comprenne les problèmes assez subtils, je ne suis pas sûr de savoir vraiment si je voulais --upgrade-only-needed et --upgrade-eager .

@xavfernandez donc vous proposez que dans la situation finale la commande soit alors pip install --upgrade-only-needed ? Ça a l'air moche.

Ce serait bien mieux d'avoir quelque chose qui correspond à l'équivalent de l'épinglage de la version sémantique disponible dans, par exemple, npm , hex ou Cargo . Cela nécessiterait certainement un ajustement dans le contexte Python, car (a) les versions de PEP 440 ne correspondent pas et ne peuvent pas correspondre précisément au versionnage sémantique et (b) la communauté Python dans son ensemble ne se soucie pas nécessairement du versionnage de type sémantique dans ses versions, même au sein de PEP 440.

Néanmoins, quelque chose dans ce sens serait très utile, tout comme la notion d'épingler une version spécifiée.

Compte tenu des contraintes, à court terme, une option viable pourrait être de faire quelque chose d'analogue aux commandes upgrade et upgrade --all d'homebrew, où cette dernière se contente de tout mettre à niveau (potentiellement avec un avertissement la première fois ).

À long terme, cependant, il serait extrêmement utile de créer des conventions partagées sur la signification des versions dans la communauté des emballages Python, et la construction d' pip support

Le chemin de migration évident serait :

pip version X :

  • ajouter des options pip install --eager , pip install --no-eager , où --eager signifie que pour les exigences sans restriction de version attachée, nous essayons d'installer la dernière version même s'il y a déjà une version installée, et --no-eager signifie que nous sommes satisfaits si une version est installée
  • ajouter également l'option pip install --eager-recursive avec la sémantique actuelle de -U
  • --no-eager reste la valeur par défaut
  • si aucune de ces options n'est spécifiée et que pip install est passé à une exigence sans numéro de version attaché, et cette exigence est déjà satisfaite, alors affiche un avertissement indiquant que nous n'avons pas mis à niveau votre package, mais à l'avenir nous le ferons, vous devez donc utiliser --no-eager si vous souhaitez conserver le comportement actuel
  • ajouter un avertissement de dépréciation à pip install -U renvoyant des personnes à pip install --eager-recursive

pip version Y :

  • changer la valeur par défaut pour pip install à --eager

version de pépin Z :

  • supprimer pip install -U

J'ai fait des versions différentes pour Y et Z parce que je suis impatient de --eager alors peut-être que nous pourrions faire ce changement sur un calendrier plus agressif, tout en gardant pip install -U un peu car beaucoup de documentation fait déjà référence à lui, et il ne cause aucun mal. Mais évidemment Y = Z est une option :-)

@chriskrycho : Tout cela semble être une bonne chose à avoir, mais cette discussion porte sur la façon de gérer la situation où l'utilisateur essaie explicitement de demander une mise à niveau vers la dernière version d'un package, ce qui est une situation qui se produit généralement déjà aujourd'hui et nous n'avons pas de bonne réponse. Je ne sais pas s'il y a encore un bogue qui demande une prise en charge de l'épinglage, mais sinon, peut-être devriez-vous en créer un ?

Absolument; mon point (que je reconnais maintenant que je n'ai absolument pas réussi à expliquer!) était simplement de noter que quelle que soit la solution adoptée ici, cela ne devrait pas entrer en conflit avec ce genre de tactique à l'avenir.

Quel est le chemin de dépréciation normal pour pip ? Basé sur l'heure/la version ? Combien de temps un élément doit-il être obsolète avant d'être supprimé ?

Soit dit en passant, je pense que "désireux" est un mot que les utilisateurs ne comprendront pas. récursif / récursif uniquement selon les besoins / toujours récursif est beaucoup plus clair.

Nous effectuons généralement un cycle de dépréciation à deux versions.

Versions majeures je suppose ? Les versions mineures sont vraiment rapides (7.0 -> 7.1 était un mois). Généralement une demi-année entre les versions majeures, donc 1 an d'avertissements d'obsolescence ?

Ouais, désolé. Versions majeures. Si nous déprécions quelque chose dans 8.x, ce sera un avertissement jaune pour le reste de 8.x, un avertissement rouge pour tout 9.x, et supprimé dans 10.x.

Merci.

Copiez le commentaire de @dstufft de https://github.com/pypa/pip/pull/3194#issuecomment -152357835 ici, car c'est le meilleur résumé de la situation :

Je suppose que le tl; dr est que je pense totalement que nous devons corriger le comportement "par défaut", nous devons juste nous contenter de l'implémentation spécifique de sa correction :

  1. Conservez l'UX be pip install --upgrade et modifiez la valeur par défaut.
  2. Déplacez l'UX vers la mise à niveau de pip avec la valeur par défaut "correcte" et ajoutez un indicateur --recursive.
  3. Déplacez l'UX vers pip install, supprimez --upgrade et ajoutez un indicateur --recursive.

Mon 2c :

(1) a une bonne UX, peut être fait maintenant
(2) UX un peu pire (avoir à la fois install et upgrade ), peut être fait maintenant
(3) deuxième meilleur UX, la modification de pip install peut être effectuée maintenant, la suppression de --upgrade ne sera effectuée que dans 10.0 (obsolète dans 8.0 et 9.0).

Je ne vois pas pourquoi le problème de compatibilité descendante (qui devrait être mineur de toute façon) pour (1) serait pire que pour (3). Donc (1) semble le mieux. Si bw compat est un vrai souci, alors choisissez (2).

Quoi qu'il en soit, il est temps d'en finir.

Je pense que la différence entre (3) et (1) se résume à savoir si nous pensons que l'installation ou la mise à niveau est l'opération la plus courante que les gens souhaitent - si c'est le cas, il est probablement préférable d'en faire la commande courte comme dans (3). De toute façon, ce n'est pas grave de toute façon.

Soit dit en passant, je pense que "désireux" est un mot que les utilisateurs ne comprendront pas. récursif / récursif uniquement selon les besoins / toujours récursif est beaucoup plus clair.

Je ne suis pas du tout attaché à l'orthographe "avide", mais récursif n'a tout simplement pas de sens en tant que mot principal pour activer et désactiver les mises à niveau. Je suppose que nous pourrions utiliser --upgrade-non-recursive (future valeur par défaut), --upgrade-recursive , --upgrade-none environ, mais cela met toujours en avant le comportement récursif déroutant (je n'aurais aucune idée de ce que --upgrade-non-recursive signifiait si je n'étais pas déjà familiarisé avec le comportement récursif étrange de l'option -U héritée), et --upgrade-none sonne de manière trompeuse comme si cela garantirait qu'aucun paquet n'est mis à niveau même si cela est nécessaire pour préserver l'auto- cohérence.

Si nous suivons cette voie, je me fiche de la période d'orthographe, car l'option que la plupart des gens veulent serait simplement la valeur par défaut et les options de mise à niveau récursive et sans mise à niveau seraient toutes deux des choses spéciales rarement utilisées que la plupart des utilisateurs pourrait ignorer.

--upgrade-non-recursive (futur valeur par défaut) ...

bien sûr, c'est déroutant. mais vous ignorez l'option la plus simple, qui n'est pas du tout de fournir ce commutateur. car s'il est identique au comportement par défaut, pourquoi en auriez-vous besoin ?

Je pense que la différence entre (3) et (1) se résume à savoir si nous pensons que l'installation ou la mise à niveau est l'opération la plus courante que les gens veulent

Je m'attendrais à "installer". Au moins, je sais que je ne mets à niveau que les packages que j'utilise massivement à dessein, mais chaque fois que je vois quelque chose d'intéressant/utile, c'est simplement à pip install pkgname .

(pas que je sois un utilisateur typique, donc mes attentes pourraient être fausses)

Je pense que je serais favorable à :

  • Pas de nouveau pip upgrade qui serait un alias pour pip install
  • pip install (sans option --upgrade* ) le comportement ne change pas
  • pip install --some_name essaierait uniquement de mettre à niveau les packages spécifiés sur la ligne de commande et non leurs dépendances
  • pip install --some_other_name pour garder l'ancien comportement --upgrade disponible

Et puis il y a deux options :

  • nous n'avons pas besoin/voulons un chemin de dépréciation, alors --some_name peut être --upgrade et --some_other_name peut être ce qui semble le mieux
  • nous avons besoin d'un chemin d'obsolescence, alors --upgrade dans pip8 donnera un avertissement indiquant qu'il est obsolète et nous devrions utiliser --some_other_name pour conserver l'ancien comportement ou plutôt passer à un --some_name plus sûr pour ne mettre à niveau les packages spécifiés et leurs dépendances que si nécessaire.

Dans ce second cas, --some_name ne peut pas être --upgrade . Nous devons donc trouver deux nouveaux noms d'options pour --some_name et --some_other_name

Il me semble que la "meilleure" solution évidente consiste à conserver pip install comme commande et à modifier le comportement de --upgrade pour ne pas mettre à niveau les dépendances. Le seul vrai problème est la compatibilité descendante, mais avons-nous eu _des_ utilisateurs faisant valoir qu'ils se fient au comportement actuel ?

Personnellement, je suis enclin à la vue "allez-y, et diable avec la rétrocompatibilité". Je pourrais argumenter que le comportement actuel est en fait un bogue, et ce changement serait une correction de bogue. Mais je pense qu'à un moment donné, nous devons être en mesure de dire que nous avons atteint un bon point, et nous allons adopter une vision beaucoup plus stricte de la compatibilité descendante. Je ne pense pas que nous en soyons encore rendus là, mais nous devrons peut-être commencer à faire savoir à la communauté ce qui, selon nous, doit encore être fait pour en arriver là.

Il y a toujours (IMO) besoin d'une sorte de commande pip install --upgrade :all: pour mettre à niveau tous les packages installés. Mais c'est une nouvelle fonctionnalité, donc ce n'est pas pertinent ici.

Le comportement actuel _est_ utile, en particulier pour des projets comme Pyramid qui ne sont pas un projet unique mais sont en fait une collection de projets. Il serait utile de pouvoir faire quelque chose comme pip install --upgrade-recursive Pyramid afin de mettre à niveau Pyramid et toutes ses dépendances vers la dernière version. Supprimer la chose récursive ensemble signifie que je dois soit rechercher manuellement toutes les dépendances et faire pip install --upgrade Pyramid dep1 dep2 dep3 dep4 (avec l'ensemble de l'arbre de dépendances), soit je dois faire un hypothétique pip install --upgrade :all: et éventuellement mettre à niveau plus choses que je veux réellement mettre à niveau. Dans #3194, au moins un utilisateur a mentionné qu'il aimerait que le comportement actuel soit disponible via un indicateur, car il est utile dans certains cas.

Y a-t-il une raison (autre que la compatibilité descendante) de ne pas faire en sorte que pip install implicitement une mise à niveau "minimale" ? J'essaie de comprendre dans quelle situation je voudrais en fait qu'il s'installe uniquement et ne fasse pas de mise à niveau (IOW, une version où la dernière version convient si je ne l'ai pas déjà installée, mais pas si je l'ai installé) et j'ai un problème avec un cas où je voudrais le comportement actuel.

J'aime l'idée d'une commande _new_ pip upgrade [--recursive] comme dans #3194 (et dépréciant install --upgrade )

J'ai des inquiétudes concernant les choix qui rompent la compatibilité ou qui ont des dépréciations complexes ou qui surchargent un pip install déjà lourd en options avec plus de modifications ou de complexité. De plus, je suis personnellement attiré par une commande "mise à niveau", qui, par défaut, ne fait que mettre à niveau de la même manière que les outils de distribution fonctionnent. « installer » s'installe et « mettre à niveau » les mises à niveau...

Je suis enclin à la vue "allez-y, et diable avec la rétrocompatibilité"

Je ne suis pas : ) au moins pour la logique de base comme celle-ci.

faire en sorte que pip install effectue implicitement une mise à niveau "minimale"

pour moi, étant donné que cela semble être un non-démarreur, n'est-ce pas ? Tenez compte du nombre de ruptures de build automatisées qui pourraient se produire. aussi, les gens se retrouvent bloqués dans un modèle conceptuel à un certain moment sur ce qu'est pip install ... et cela forcerait le rechargement d'un nouveau modèle mental. les gens n'aiment pas ça.

@qwcode Je ne sais pas, je ne pense pas que ce serait OK. Le principal problème avec pip upgrade est soit vous supprimez le moyen pour les gens de dire "donnez-moi la dernière version de ceci, qu'il soit installé ou non" ou vous avez deux commandes qui font presque entièrement la même chose ( pip install et pip upgrade ). Il pourrait y avoir des cassures à court terme, mais je suis un peu inquiet au sujet du modèle mental réel de pip upgrade parce que je peux voir des gens très répandus remplacer leurs instructions d'installation de pip install foo à pip upgrade foo (mais pourquoi est-ce que je mets à jour quelque chose que je n'ai pas déjà installé ?!).

Euh, je pense que ce serait OK je veux dire.

large diffusion remplaçant leurs instructions d'installation pip install foo à pip upgrade foo

roger, c'est pourquoi je pense que upgrade devrait simplement être mis à niveau. en ce qui concerne l'"étron" --fill-in-missing , je ne suis pas coincé là-dessus, alors ne me prenez pas pour dire que je dois l'avoir, mais voyez ci-dessous.

"donnez-moi la dernière version de ceci, qu'elle soit installée ou non"

  • si je n'ai pas FOO , alors je pip install FOO et j'obtiens la dernière version.
  • si j'ai FOO , alors pip upgrade FOO et j'obtiens la dernière version.

Je pense qu'on parle de 2 cas :

  1. Je ne sais pas si j'ai FOO , et je veux que la commande _one_ obtienne le dernier FOO , que je l'aie ou non.
  2. Je veux que la commande _one_ obtienne le dernier de FOO et BAR . J'ai FOO installé, mais pas BAR .

Doit-on aux utilisateurs la commande _one_ pour ceux-ci ? Je préférerais la simplicité et la clarté des commandes plutôt que de donner des raccourcis aux gens. Mais si les utilisateurs le demandent, c'est là qu'intervient quelque chose comme --fill-in-missing .

De plus, je suis personnellement attiré par une commande "mise à niveau", qui, par défaut, ne fait que mettre à niveau de la même manière que les outils de distribution fonctionnent. « installer » s'installe et « mettre à niveau » les mises à niveau...

Point de clarification : je viens de vérifier le fonctionnement de trois outils de distribution populaires et AFAICT (en partie basé sur les pages de manuel b/c je n'utilise pas tous ceux-ci moi-même):

  • apte:

    • apt install <pkg> effectue un "upstall" -- soit des mises à niveau, soit des installations selon qu'il est déjà installé ou non.

    • apt upgrade met

    • apt upgrade <pkg> n'existe pas, la seule façon de mettre à niveau un seul package est apt install <pkg> (qui accepte également différents types de spécificateurs de version)

  • Miam:

    • yum install <pkg> effectue un "upstall"

    • yum upgrade met

    • yum upgrade <pkg> met

  • homebrew :

    • brew install <pkg> effectue un "upstall"

    • brew upgrade met

    • brew upgrade <pkg> met

Donc, utiliser install pour les mises à niveau est en fait ce que font les outils de distribution :-). Cela ne veut pas dire que nous devons le faire aussi ; juste un point de données.

Je ne sais pas si j'ai FOO, et je veux une commande pour obtenir le dernier FOO, que je l'aie ou non.

Je pense que le cas d'utilisation le plus évident pour cela est dans la documentation. Exemple : les documents django que j'ai liés dans l'autre fil qui demandent aux gens d'exécuter pip install -U <some package> . Vous ne voulez pas dire aux gens de "exécuter pip install <pkg> sauf si vous l'avez déjà installé, exécutez pip upgrade <pkg> " parce que c'est beaucoup trop déroutant pour les débutants, mais si install ne le fait pas t mettre à niveau, puis simplement dire aux gens d'exécuter pip install <pkg> va également créer une confusion où les gens commencent à travailler sur votre didacticiel avec une ancienne version installée et n'ont aucune idée de pourquoi les choses ne fonctionnent pas correctement et vous en blâment. Vous avez donc certainement besoin d'une seule commande "upstall", et elle doit être simple et évidente à inclure dans les documents.

Suivi du comportement de Homebrew pour comparaison : brew upgrade échoue si vous essayez d'installer un package non installé :

$ brew upgrade git
Error: No such file or directory - /usr/local/Cellar/git

De plus, le comportement actuel de brew upgrade est en train de changer (voir la discussion ici ); dans une future version, il exigera --all pour mettre à niveau tous les packages installés.

Point de clarification

Je savais que quelqu'un relèverait ça. : )
J'ai failli me répondre. J'étais concentré sur les mises à niveau.

miam surclassement[...] Je ne sais pas ce qui se passe s'ils ne sont pas déjà installés.

ça ne fait rien

miam installereffectue un "upstall"

true, mais le comportement par défaut est de demander une confirmation, ce que pip n'a pas.

les docs django que j'ai liées dans l'autre fil

pour être clair, il ne s'agissait pas des véritables documents Django. les docs de Django disent pip install Django (https://docs.djangoproject.com/en/1.8/topics/install/)

c'est en fait une mauvaise chose, je pense, étant donné la façon dont -U fonctionne actuellement, pour amener les gens à s'habituer à utiliser install -U .

dans votre exemple lié, c'était pour redis qui n'a pas de dépendances je pense, donc ça va dans ce cas.

va créer de la confusion là où les gens commencent à travailler sur votre didacticiel
avec une ancienne version [...] Vous avez donc absolument besoin d'une seule commande "upstall"

IDK, ce n'est pas si évident pour moi que les tutoriels devraient dire aux gens de monter en puissance en général. Si quelqu'un fait un tutoriel pour FOO, et qu'il a déjà FOO installé, alors peut-être qu'il ne devrait pas "upstaller" aveuglément... peut-être qu'une mise à niveau endommagerait l'environnement existant.

Je pense que les didacticiels devraient dire aux gens de « upstaler » (un bon terme !) Parce qu'un bon nombre d'entre eux sont écrits par les projets eux-mêmes et lorsque les gens consultent des didacticiels, ils regardent rarement d'abord quelle est la version existante de FOO qu'ils ont installé est, ils ont plutôt tendance à aller regarder quels que soient les derniers documents.

Je suis également d'accord sur le fait que la façon dont -U fonctionne actuellement, c'est une mauvaise habitude d'amener les gens à l'utiliser sans discernement, mais l'essentiel à mon avis est le comportement proposé, je ne pense pas que ce soit une mauvaise habitude , mais plutôt une bonne chose à faire. Si vous devez vous assurer qu'une version particulière est installée, vous devriez déjà utiliser == et nous pouvons ajouter un indicateur pour transformer le "upstall" par défaut en une "installation" simple pour les personnes qui doivent s'assurer que la version actuellement installée OU la dernière version est installée (bien que je ne puisse toujours pas proposer un scénario dans lequel c'est réellement ce que tout le monde veut).

Je pense que les tutoriels devraient dire aux gens de « upstaler »

Encore une fois, cependant, quel est cet environnement dans lequel ils se trouvent, où il est évidemment possible de mettre à niveau ? S'il s'agit d'un environnement python de système de distribution, alors certainement pas. S'il s'agit d'un autre environnement, qu'ils ont créé pour une application, alors un décrochage pourrait être dommageable. s'il s'agit d'un environnement qu'ils viennent de créer pour le didacticiel, ils n'ont pas besoin de le mettre à niveau.

un point clé ici est que PyPI n'est pas un référentiel "organisé", comme le sont les référentiels de distribution. vous pouvez être à peu près assuré qu'un "upstall" est à l'abri d'un référentiel de distribution par défaut... vous ne le savez pas avec PyPI. Chaque mise à niveau est un peu un pari. "install", tel qu'il est, est conservateur.

gardez à l'esprit que faire en sorte que pip install agisse comme un "upstall" sans corriger #988 va casser les choses.

considérez où A et B sont installés et A nécessite B<2 . Maintenant, je vais exécuter le nouveau pip install B , qui installe B en v3 ou autre (en raison de ne pas tenir compte des contraintes installées), et maintenant mon environnement est détruit.

pour les personnes qui doivent s'assurer que la version actuellement installée OU la dernière version est installée (bien que je ne puisse toujours pas proposer un scénario dans lequel c'est réellement ce que tout le monde veut).

Il est trivial de proposer de tels scénarios. Exemple (malheureusement non inventé) : actuellement statsmodels est cassé par le dernier pandas (0.17.0). Je suis un utilisateur des deux. J'ai un tas de versions de Python installées et des venvs qui traînent. Je sais donc que pour tout Python/venv, j'aimerais installer pandas seulement s'il n'est pas encore là. Si c'est le cas, j'aurai probablement aussi statsmodels et ensuite "upstall" le cassera.

@rgommers Hmm, vous êtes donc absolument sûr de ne pas avoir de pandas 0.17.0 dans un environnement virtuel ? Je suppose que cela pourrait arriver bien que je pense que je l'épellerais probablement en faisant pip install pandas!=0.17.0 ou pip install pandas<0.17 mais je suppose qu'il n'est pas tout à fait déraisonnable de se fier à ce que vous avez déjà installé.

Hmm, vous êtes donc absolument sûr de ne pas avoir de pandas 0.17.0 dans un environnement virtuel ?

Ce n'est pas ce que j'ai dit. J'ai un venv avec pandas 0.17.0, juste un dans lequel je n'ai pas de statsmodels. pip install pandas<0.17 fera le travail, mais je n'avais pas pensé à l'utiliser (principalement parce que je n'en avais pas besoin, la commande install fonctionne à cette fin).

De toute façon, je n'ai pas vraiment de préférence pour ou contre l'upstall. Je voulais juste souligner un scénario réaliste lorsque vous avez dit que vous ne pouviez pas en proposer un.

+1

Cette discussion semble avoir piétiné sans parvenir à une conclusion. Toute option sur la table est une amélioration majeure par rapport à la situation actuelle. Il semble que tous les avantages et inconvénients pertinents aient été pris en compte ; il n'y a qu'une différence d'opinion sur l'importance relative de la rétrocompatibilité par rapport à l'API optimale. Peut-être que les développeurs de pip peuvent tenter de finaliser une décision ?

@rgommers ils ont probablement pris une décision? https://pip.pypa.io/en/stable/user_guide/#only -if-needed-recursive-upgrade

@rgommers ils ont probablement pris une décision? https://pip.pypa.io/en/stable/user_guide/#only -if-needed-recursive-upgrade

@ Liso77 merci, mais non - c'est vraiment la discussion sur ce fil qui doit être finalisée. Cette documentation à laquelle vous avez lié renvoie juste ici.

@rgommers à partir du lien que j'ai posté ci-dessus, j'ai lu que les développeurs allaient créer une commande de mise à niveau. Et ne prévoyez pas d'ajouter l'option "seulement si nécessaire" pour installer la commande car ils n'ont pas créé de terme pour cette option et n'utilisent que la description entre guillemets. Donc d'après votre commentaire (ou celui de dstuff) le 30 octobre - c'est : _2. Déplacez l'UX vers la mise à niveau de pip avec la "bonne" valeur par défaut..._ (d'ailleurs, je préfère cela)
Je suis sûr que vous pensiez davantage à ce sujet et que vous voyez des choses plus subtiles que moi. Alors s'il vous plaît écrivez ce qui (si vous pensez que quelque chose) est encore ouvert. Si vous vouliez dire qu'il pourrait être bon que les développeurs écrivent ici explicitement leur décision et finissent par clore ce problème - je suis d'accord.

D'ailleurs. situation pourrait être beaucoup moins problématique si nous avions quelque chose comme

pip freeze > checkpoint.txt
pip checkout checkpoint.txt

ce qui pourrait garantir le retour de l'installation à n'importe quel « point de contrôle ». (pip install -r n'est pas bon en ce moment) Je pensais ajouter cette proposition dans un nouveau numéro mais je suis sûr que je dois étudier et analyser davantage pour apporter une proposition vraiment utile. Je vois qu'il y a beaucoup de mises en garde mais j'aime vraiment avoir la possibilité de

pip checkout git+https://github.com/somebody_trusted/pip_distro4ubuntu<strong i="12">@bleeding_egde_branch</strong>
#or
pip checkout git+https://github.com/somebody_trusted/pip_distro4ubuntu<strong i="13">@stable</strong>

Je veux dire que cela pourrait résoudre (avec l'aide de quelqu'un_trusted (ou d'une communauté avec beaucoup de tests unitaires)) quelque chose comme le problème des pandas et des modèles de statistiques que vous avez décrit ci-dessus.

(utile à voir pour ce sujet est aussi : https://pypi.python.org/pypi/peep)

@Liso77 c'est simple : la discussion sur cette question n'est pas terminée. Il y a un PR en attente avec la commande upgrade implémentée (gh-3194), mais les développeurs pip (au moins qwcode et @dstufft , et probablement aussi @xavfernandez et @pfmoore) doivent décider si c'est ce qu'ils veulent , ou ils veulent changer le comportement de pip install place. Jusqu'à ce que cela se produise, rien ne changera.

+1

Ainsi, il semble que l'introduction de la nouvelle commande de mise à niveau ait été acceptée et le dernier débat en suspens est de savoir s'il devrait y avoir ou non une commande "upstall" et si oui, quelle commande principale (installation ou mise à niveau) devrait l'obtenir comme commutateur ou par défaut .

J'ajoute mes opinions personnelles :

Je pense qu'avoir une commande singulière à sécurité intégrée pour l'installation en vaut la peine, _si seulement_ pour les cas où vous souhaitez vérifier par programme qu'un environnement est à jour pour une raison quelconque. Pourquoi « par programmation » ? Parce qu'il n'est pas interactif, c'est-à-dire qu'il n'y a pas d'utilisateur pour réagir à une erreur, un avertissement ou un autre message le dirigeant vers la commande frère ou sœur car un package existe ou n'existe pas déjà.
En option, une invite pourrait être ajoutée pour demander à l'utilisateur s'il souhaite mettre à niveau ou installer au lieu de simplement se plaindre.

Cela dit, cette commande "upstall" ne doit pas être la valeur par défaut de l'une ou l'autre des commandes (installation/mise à niveau) et nécessite donc l'appel d'une option. Cela ajoute de la clarté aux verbes « install » et « mise à niveau » clairement définis sur le plan sémantique, et à mon avis, tous les gestionnaires de packages qui installent par défaut l’un d’entre eux le font mal. Inciter à l'action (comme yum semble le faire) est bien.

Cela nous laisse avec upgrade --install (plus court que --install-missing ) et install --upgrade . Sémantiquement, "mettre à niveau vers la dernière version [et installer si n'existe pas]" et "installer la dernière [ou mettre à niveau vers la dernière si elle existe déjà]". Pas beaucoup de différence ici imo. install --upgrade est la version déjà existante et serait reconnaissable, mais rétrocompatible.
En voici une autre pour le mix : une nouvelle commande nommée install-upgrade (ou upstall ?), où ni l'installation ni la mise à niveau n'ont l'option de "faire aussi l'autre" mais une nouvelle commande est introduite avec sémantique claire dans une position importante : le nom de la commande elle-même. Ce serait ma préférence.

TL;DR : Introduisez upgrade et upgrade-install , désapprouvez install --upgrade . Toutes les fonctionnalités avec une sémantique claire.
Ajoutez des messages ou éventuellement des invites pour installer et mettre à niveau des commandes si leurs opérations échouent en raison d'un package déjà existant ou non.

Je l'ai encore fait manuellement ce matin. Y a-t-il des nouvelles sur cette demande de fonctionnalité ?

+1

+1

+1

Tout le monde, veuillez utiliser la réaction du pouce levé sur le PO et arrêtez de spammer la boîte de réception de tout le monde.

puisque pip a un modèle d'assurance qualité différent de celui des distributions Linux, j'en suis à peu près certain, une mise à niveau aléatoire de toutes les commandes n'est qu'une rupture en cours

pypi n'a pas de base de données de versions de packages et de compatibilité réellement vérifiée et testée,
donc contrairement à une distribution avec QA, pypi n'a pratiquement pas de propre QA et repose entièrement sur les projets qui y sont téléchargés (qui varient en qualité)

avec les contraintes actuelles, je suis convaincu que c'est plus une malédiction qu'une bénédiction
et si quelqu'un se demande pourquoi les distributions sont si obsolètes, le contrôle qualité prend du temps et des efforts ^^

Tout le monde, veuillez utiliser la réaction du pouce levé sur le PO et arrêtez de spammer la boîte de réception de tout le monde.

Notez que nous n'avons en fait besoin d'aucune sorte de réponse « J'aimerais ça » de la part des gens. Nous sommes conscients que les gens veulent cela, ce qui manque, c'est quelqu'un qui est prêt à développer un correctif qui réponde à toutes les diverses préoccupations et problèmes qui ont déjà été soulevés, et qui apparaîtront inévitablement lors d'un examen des relations publiques.

Donc personnellement, j'apprécierais que les gens s'abstiennent de signaler ce problème à moins qu'ils n'aient un code fonctionnel qui offre au moins un point de départ pour la mise en œuvre - et qu'ils soient prêts à le suivre jusqu'à la mise en œuvre.

Sinon, nous y arriverons quand nous le pourrons. Personnellement, je rencontre régulièrement ce problème et je suis un développeur de base de pip, je peux donc garantir que si jamais j'ai suffisamment de temps moi-même pour y travailler, je le ferai. En attendant, « des progrès ? » les commentaires ont tendance à simplement me démotiver parce qu'ils ont surtout l'impression que des gens exigent le droit de dicter la façon dont je passe mon temps libre...

un point de départ pour la mise en œuvre

Je pensais que c'était le but de https://github.com/pypa/pip/pull/3194? À partir de là, la discussion a dérivé vers plusieurs alternatives pour le nom et le comportement des commandes sans un consensus de la part des développeurs principaux. Cela aiderait-il à mettre en œuvre plusieurs de ces alternatives ? Ou https://github.com/pypa/pip/pull/3194 a-t-il simplement besoin d'un rafraîchissement ?

@sfriesel Vous avez manqué "et êtes prêt à le suivre". On dirait que la personne qui a fait ce PR a manqué de temps ou d'intérêt (un problème courant). La prochaine étape à ce sujet est probablement pour le PO ou quelqu'un d'autre qui est prêt à prendre en charge le PR, pour rédiger un résumé de style PEP de la position actuelle, quelles sont les différentes questions en suspens, ce qu'il suggère comme le résolution de ces différents problèmes et un appel à commentaires pour relancer la discussion. Si le débat est trop important pour github, il doit peut-être apporter son document à distutils-sig pour plus d'informations. S'il ne peut pas décider d'une résolution qui lui convient pour les différentes questions, ou ne peut pas obtenir un consensus à partir du débat, alors oui, #3194 est probablement mort (jusqu'à ce que quelqu'un d'autre reprenne le problème, auquel moment je J'espère qu'ils incorporeront tout le travail effectué dans leur nouveau PR).

Plus de 50 % du travail sur une proposition comme celle-ci relève de la « gestion » (documentation des propositions, gestion des discussions, recherche de consensus). Ce n'est pas nécessairement ce que les gens aiment faire, mais avec une base de code aussi largement utilisée que pip, c'est une partie essentielle. (Et oui, c'est un problème - il est bien plus agréable de dire "J'écris du code en tant que passe-temps" que "Je fais de la gestion de projet en tant que passe-temps" :-))

@pfmoore Tout à fait d'accord.

Le nombre de propositions et la quantité de discussions, réparties dans de nombreux endroits, liées à cette question au fil des ans, rendent extrêmement difficile l'approche de cette question et l'obtention d'une image claire en peu de temps .


@RonnyPfannschmidt

pypi n'a pas de base de données de versions de packages

C'est vrai. Il s'agit d'informations fournies par les packages au moment de l'exécution (du fichier setup.py) et cela ajoute un peu plus de complexité au processus de résolution des dépendances. De plus, en raison du comportement de la logique actuelle, certains packages (même les plus importants comme scipy) ne répertorient pas de dépendance (comme numpy) s'il est installé pour éviter de le recompiler inutilement.

Cela serait résolu par le PEP 426 , entre autres, mais je ne sais pas quel est le statut de ce PEP.

@pfmoore

Notez que nous n'avons en fait besoin d'aucune sorte de réponse « J'aimerais ça » de la part des gens

Il est juste tentant de dire +1 ou de mettre un pouce levé pour dire que vous aimeriez que cela se produise. Cela donne à la personne le sentiment d'avoir ajouté un petit quelque chose à ce problème, d'y avoir contribué. Je ne dis pas que les développeurs de pip doivent être motivés ou persuadés, c'est juste que tout le monde veut le dire. Et...

J'apprécierais que les gens s'abstiennent de signaler ce problème à moins d'avoir un code fonctionnel

Mettre un pouce levé ne donnera à personne de notifications/e-mails (ennuyeux) et nous pouvons toujours voir le nombre de personnes qui ont manifesté leur intérêt. Je pense que personne ne devrait s'en soucier, mais je peux me tromper.

Mettre un pouce levé ne donnera à personne de notifications/e-mails (ennuyeux) et nous pouvons toujours voir le nombre de personnes qui ont manifesté leur intérêt. Je pense que personne ne devrait s'en soucier, mais je peux me tromper.

Ah, je n'avais pas réalisé que faire ça évitait les notifications. Oui, c'est une bonne idée.

La prochaine étape à ce sujet est probablement pour le PO ou quelqu'un d'autre qui est prêt à prendre en charge le PR, pour rédiger un résumé de style PEP de la position actuelle, quelles sont les différentes questions en suspens, ce qu'il suggère comme le résolution de ces différents problèmes et un appel à commentaires pour relancer la discussion.

Pour ce que ça vaut, je faisais plus tôt un article sur cette résolution de dépendances, style PEP. Je vais le diviser et le mettre à jour maintenant, en ajoutant toutes les choses qui ont été proposées au cours des derniers mois. Je publierai celle pour la commande de mise à niveau en tant que Gist une fois que ce sera fait (~ 2 jours?)

Je ne suis pas encore prêt à reprendre la propriété du PR. J'ai l'intention d'aider à relancer les discussions et d'arriver à une conception finale qui peut être mise en œuvre. Si des choses autour de moi va au plan, je devrais être en mesure de suivre cette mise en œuvre , mais grâce à je ne veux pas engager à ce qui suit cela par instant.

/cc @qwcode @dstufft @pfmoore @xavfernandez

Voici le lien vers mon article : https://gist.github.com/pradyunsg/a5abeac4af90fbdc54bb266c32c0d2d8

Au départ, je me suis contenté de créer des liens vers divers endroits (~ 30 liens) auxquels le lecteur peut se référer et j'ai essayé de copier puis de modifier pour adapter tous les fils de commentaires. Le document était assez long et mes opinions se sont glissées. J'ai fini par repartir de zéro. C'est plus court maintenant et pas opiniâtre. Je l'ai quand même marqué comme WIP.

S'il y a des problèmes, veuillez commenter l'essentiel. Je ferai les corrections dès que possible.

AVERTISSEMENT : _LEGER_ LONG COMMENTAIRE AVANT


J'aime l'idée de corriger le comportement --upgrade existant. Y a-t-il des problèmes à ce sujet, à part la compatibilité descendante ? L'ajout d'une commande upgrade ne semble pas être une bonne idée, en raison du chevauchement élevé entre l'installation et la mise à niveau.

FWIW, git a fait quelque chose de similaire à ce dont nous discutons à propos de --upgrade , en modifiant le comportement par défaut de git push en 2014. lien

S'il y a un intérêt à changer le comportement de pip install --upgrade , voici une proposition d'amorçage (appelez-la P1) pour cette discussion :

  • À partir de la prochaine version majeure (9.0), pip install --upgrade affiche un avertissement :

```
PipDeprecationWarning : pip arrêtera la mise à niveau des dépendances vers leur dernière version
version inconditionnellement par défaut à partir de la version 11.0.

Pour conserver le comportement actuel après les changements de comportement par défaut, pour
la commande d'installation passe --upgrade-strategy eager .

Pour commencer à utiliser le nouveau comportement immédiatement, à la commande install
passer --upgrade-strategy non-eager .

Pour étouffer ce message,.

Pour plus de détails, lisez.
```

La page de documentation liée fournirait un aperçu rapide du changement et de ses effets. Il répondrait alors à la question la plus courante : « Que dois-je faire ? » et "Quelle stratégie de mise à niveau dois-je utiliser ?" de la manière la plus directe raisonnable.

  • Le message pourrait utiliser un nettoyage.
  • L'option pourrait même être 2 drapeaux, --upgrade-eager et --upgrade-non-eager ou quelque chose comme ça. C'est le bikeshedding, c'est-à-dire la dernière étape.

    • À moins que quelque chose de grave ne se produise, dans la version 11.0, pip install --upgrade change de comportement pour ne pas être impatient lors de la mise à niveau des dépendances.

Edit : j'ai mis un cycle de 3 versions majeures pour le changement, juste pour donner plus de temps aux gens pour basculer. C'est peut-être inutile. Peut-être qu'une version majeure imprimant des avertissements et la suivante faisant le changement est suffisante ?

@dstufft avait eu une idée similaire (la même ?).


Si une commande de mise à niveau est la voie à suivre, voici une proposition d'amorçage pour relancer cette discussion (appelez-la P2, si vous le souhaitez) :

  1. pip upgrade copie la plupart des options et comportements à partir de pip install .
  2. --dry-run drapeau install et upgrade qui affichent quel pip essaiera s'il était réellement exécuté.
  3. pip install <out_of_date_pkg> ne change pas le comportement.
  4. pip upgrade <not_installed_pkg> échouerait.
  5. pip upgrade <up_to_date_pkg> ne ferait rien, dira pourquoi il n'a rien fait et sortira avec un code de sortie nul.
  6. pip upgrade <out_of_date_pkg> effectuerait une mise à niveau récursive non impatiente.

    • :white_check_mark : mise à niveau récursive par défaut

  7. pip upgrade --eager package se comporterait comme le pip install --upgrade .

    • :white_check_mark : autoriser l'inscription au comportement actuel

  8. pip install --upgrade imprimerait un RemovedInPip10Warning .
    Parce qu'il serait supprimé.

De plus, que pensez-vous de :

  1. Rendre la commande de mise à niveau interactive ? (quelque chose comme ce que fait apt-get)

    • faire en sorte que pip install <pkg> se comporte comme l'installation du gestionnaire de packages du système d'exploitation ?

  2. Avoir --only-binary par défaut dans la nouvelle commande de mise à niveau ?

    • Si tout va bien, qu'en est-il de l'ajout de --only-source et --no-source dans la commande de mise à niveau ?

  3. Ajouter une option pour "tenir" la mise à jour d'un package ? OMI, il s'agit d'une exigence pour upgrade-all .
  4. Est-il judicieux de faire la distinction entre ces cas, c'est-à-dire d'exiger une CLI différente ?

    • installer : non installé -> à jour

    • mise à jour : obsolète -> à jour

    • upstall : {non installé, obsolète} -> à jour

Je n'ai rien proposé à propos de "l'installation en tant qu'upstall" parce que je ne le sens pas fortement de toute façon. Il est cohérent avec les gestionnaires de packages au niveau du système d'exploitation, mais constituerait un changement majeur. Je ne sais pas à quel point cela serait utile ou à quoi ressembleraient le comportement et l'interface exacts ...

Peut-être que dormir là-dessus pourrait aider.

Personnellement, je ne vois pas beaucoup d'intérêt à rester cohérent avec un comportement dont peu ou pas de personnes sont satisfaites. Je me demande si en avoir un pour Python 2 (embrassant la stabilité) et un autre pour Python 3 (embrassant le changement) serait mieux ou pire.

@ekevoo

Je me demande si en avoir un pour Python 2 (embrassant la stabilité) et un autre pour Python 3 (embrassant le changement) serait mieux ou pire.

Un, c'est hors sujet. Deuxièmement, si vous le faites, il y aura finalement divergence. Cela aliénera les personnes utilisant actuellement Python 2 car il atteindra (espérons-le) un jour EOL et ils devront passer à Python 3, devant s'adapter à un outil qui se comporte différemment. Ainsi, pip ne devrait pas faire de divergence (et ne le fera pas, IMO). Autant le garder ensemble dans un seul outil alors.

OTOH, je vois ce que vous pensez de la compatibilité descendante acceptable...

Un avertissement dans le pip 9, ainsi que des options supplémentaires pour modifier le comportement de pip install --upgrade , --eager/non-eager (ou un autre nom) me semblent bien.

Cogner. Une autre notification pour tout le monde.

@pfmoore @dstufft @qwcode Je ne veux pas être curieux mais pourriez-vous s'il vous plaît prendre du temps pour cela, le week-end ou la semaine à venir ?

Bon alors mes commentaires :

Concernant les deux voies, je n'ai pas d'opinion. Choisissez celle que vous jugez être la meilleure option, mettez-la en œuvre et nous verrons comment cela se passe à partir de là.

Concernant vos questions supplémentaires :

  1. Je suis -1 pour rendre la commande interactive. À moins qu'il n'y ait un problème spécifique sur lequel l'utilisateur doit prendre une décision, du genre "cette conséquence de ce que vous avez demandé est quelque chose dont vous n'étiez clairement pas au courant, et pourrait être un problème - voulez-vous continuer" alors c'est juste bruit inutile. Je suis contre les invites "êtes-vous sûr" en général. Si vous avez une proposition spécifique pour une invite qui, selon vous, mérite d'être ajoutée, n'hésitez pas à demander à nouveau avec les détails inclus.
  2. Nous ne devrions pas faire des mises à niveau différentes des installations, donc pas de --only-binary par défaut. Pour mon usage personnel, je voudrai probablement toujours pip upgrade --only-binary en premier lieu, mais je _veut_ que ce soit explicite.
  3. Je ne sais pas ce que vous entendez par "conserver" les mises à jour. Précisez s'il vous plaît. Mais en guise de réponse générale, je dirais que ne vous embêtez pas dans un premier temps, gardons le PR initial exempt de « extras facultatifs » - ils peuvent être ajoutés plus tard.
  4. N'est-ce pas là le principal sujet de débat sur les différentes discussions de cette fonctionnalité ? Pour commencer, cela n'affecte-t-il pas la question de base de install --upgrade vs upgrade ? Je ne me souviens pas qu'il y ait eu une résolution de cette question, donc je suis un peu surpris que vous vous attendiez à une réponse "simple" à celle-ci ? Je n'ai certainement pas de bonne réponse.

(Au fait, je n'ai pas un accès facile à l'essentiel, donc s'il y a du contenu là-dedans qui ne figure pas dans votre résumé, je l'ai raté désolé).

Je sais que c'est un travail difficile d'écrire un PR, et démotivant de le voir s'enliser dans des débats et des questions, mais en fin de compte, je pense que quelqu'un va devoir en écrire un, et le présenter comme "c'est la solution Je propose - des commentaires ?"

Nous ne devrions pas faire des mises à niveau différentes des installations [snip] Je voudrai probablement toujours pip upgrade --only-binary en premier lieu, mais je veux que ce soit explicite.

Si vous voulez probablement toujours quelque chose, ce devrait être la valeur par défaut 1 . Mais je pense que maintenir la cohérence entre install et une éventuelle commande upgrade est une bonne idée.

Je ne sais pas ce que vous entendez par "conserver" les mises à jour.

Je vais laisser cela reposer jusqu'à ce que nous en arrivions à parler d'ajouter une fonctionnalité de mise à niveau complète.

note à moi-même : apt-mark concepts pour pip

Je suis -1 pour rendre la commande interactive. Sauf s'il y a un problème spécifique sur lequel l'utilisateur doit prendre une décision

Idem.

N'est-ce pas là le principal sujet de débat sur les différentes discussions de cette fonctionnalité ?

Exactement pourquoi je voulais savoir ce que vous en pensez.

Je ne me souviens pas qu'il y ait eu une résolution de cette question, donc je suis un peu surpris que vous vous attendiez à une réponse "simple" à celle-ci ?

Je ne m'attends pas encore à une réponse "simple". J'espère que nous arriverons à une réponse, de préférence simple, grâce à la discussion.

Soit dit en passant, je n'ai pas facilement accès à l'essentiel, donc s'il y a du contenu là-bas qui n'est pas dans votre résumé, je l'ai raté désolé

Plus qu'un résumé, c'est un suivi de la rédaction. Veuillez le lire dès que vous le pouvez.

Choisissez celle que vous jugez être la meilleure option, mettez-la en œuvre et nous verrons comment cela se passe à partir de là.
[couper]
Je pense que quelqu'un va devoir en écrire un [PR], et le publier comme "c'est la solution que je propose - des commentaires ?"

Je pensais dans le sens de « déterminons exactement ce que nous voulons d'abord », puis allons-y et implémentons-le.


1 à moins que cela ne brise le monde de quelqu'un d'autre

Nous ne devrions pas faire des mises à niveau différentes des installations [snip] Je voudrai probablement toujours pip upgrade --only-binary dans un premier temps, mais je veux que ce soit explicite.
Si vous voulez probablement toujours quelque chose, cela devrait être par défaut. Mais je pense que maintenir la cohérence entre l'installation et une éventuelle commande de mise à niveau est une bonne idée.

Si _tout le monde_ veut probablement toujours quelque chose, cela devrait (peut-être) être une valeur par défaut. Mais je commentais simplement mes propres préférences. Honnêtement, je ne sais pas si --only-binary est ce que la plupart des gens voudraient (cela dépend probablement de si nous parlons à long ou à court terme).

Il existe une grande différence entre les binaires (roues), les sources qui peuvent être construites n'importe où (généralement du Python pur) et les sources qui nécessitent un compilateur ou d'autres prérequis externes. Malheureusement, pip ne peut pas distinguer les deux derniers, ce qui rend --only-binary moins utile (en particulier par défaut).

Et j'apprécie la cohérence entre les commandes par rapport aux valeurs par défaut "faites ce que je veux dire", ce qui peut encore être ma préférence personnelle.

Plus qu'un résumé, c'est un suivi de la rédaction. Veuillez le lire dès que vous le pouvez.

Je l'ai lu, il n'a pas ajouté grand-chose dont je n'étais pas au courant (car j'ai suivi les différents fils de discussion à ce sujet), donc mes commentaires sont maintenus. Mais c'est un bon résumé de l'état des lieux, alors merci de l'avoir écrit.

Nous ne devrions pas faire des mises à niveau différentes des installations [snip] Je voudrai probablement toujours pip upgrade --only-binary dans un premier temps, mais je veux que ce soit explicite.

Si vous voulez probablement toujours quelque chose, cela devrait être par défaut. Mais je pense que maintenir la cohérence entre l'installation et une éventuelle commande de mise à niveau est une bonne idée.

Si _tout le monde_ veut probablement toujours quelque chose, cela devrait (peut-être) être une valeur par défaut. Mais je commentais simplement mes propres préférences.

Clarification : le "vous" dans mon commentaire faisait référence aux utilisateurs finaux (au pluriel), @pfmoore en étant un dans ce cas spécifique. J'aurais vraiment dû utiliser un autre mot.

Quelques réflexions sur les stratégies de mise à niveau. Avis perso, tout ça bien sur :-)

Supposons que je fasse pip upgrade foo

  1. Si je n'ai pas actuellement foo installé, je m'attends à une erreur. Pour moi, "installer" et "mettre à niveau" sont deux activités distinctes que je ne souhaite pas fusionner.
  2. S'il n'y a pas de version disponible plus récente que celle actuellement installée (voir ci-dessous concernant --only-binary ), j'attends une notification indiquant qu'il n'y a rien à faire.
  3. Sinon, je m'attends foo ce que

    • Je ne suis pas convaincu que l'ajout de contraintes ait du sens. Que signifierait pip upgrade foo>1.0 si j'avais 1.1 installé mais que 1.2 est disponible ? Ce n'est pas une mise à niveau s'il laisse 1.1 là, mais s'il passe à 1.2, c'est la même chose que pip upgrade foo . Vous pourriez peut-être attribuer un sens à quelque chose comme pip upgrade foo<2.0 mais IMO ce serait un cas très inhabituel, et ne vaut pas la complexité. Supposons donc que pip upgrade ne prenne qu'une liste de noms de packages (par opposition aux exigences).

    • De même, je ne sais pas comment interpréter pip upgrade <path_to_archive/wheel> . Supposons que ce ne soit pas autorisé dans un premier temps.

  4. Je peux ou non permettre à pip d'essayer de construire à partir de la source (cela doit être une décision de l'utilisateur, car pip ne peut pas dire si la construction à partir de la source fonctionnera, et n'a pas la possibilité d'essayer à nouveau avec une version différente si un la compilation de la source échoue). Ainsi, --only-binary doit être une option de l'utilisateur et, si elle est spécifiée, cela signifie que pip doit ignorer la distribution des sources lors de l'élaboration de "ce qui est disponible". (Nous pourrions bien sûr utiliser par défaut uniquement les binaires et avoir une option --allow-source , mais dans tous les cas, upgrade devrait correspondre à install à cet égard).

OK, cela gère donc les packages explicitement spécifiés. Je doute qu'il y ait quelque chose de controversé là-dedans (sauf peut-être pour les parties que je dis que nous devrions omettre jusqu'à plus tard). Passons maintenant aux dépendances.

  • La règle principale dans mon esprit est que nous ne devons jamais rien faire aux dépendances, à moins que nous ne mettions _réellement_ à niveau le package spécifié par l'utilisateur. C'est donc le point de départ. Si la cible n'est pas mise à niveau, ne regardez même pas les dépendances. Jamais.
  • Mon point de vue serait que _toutes_ les dépendances doivent être traitées de la même manière - qu'elles soient des dépendances directes ou indirectes du package spécifié par l'utilisateur, cela n'a pas d'importance. Je ne pense pas que ce soit controversé.
  • Une hypothèse fondamentale ici devrait être que l'utilisateur ne sait pas quelle est la liste des dépendances. Après tout, l'intérêt d'avoir des dépendances implicites est que l'utilisateur _n'a pas_ à les gérer. Ainsi, à mon avis, toute solution qui nécessite que l'utilisateur connaisse explicitement une dépendance est imparfaite (à moins qu'une commande échoue avec un message concernant une dépendance particulière, auquel cas l'utilisateur peut réexécuter avec cette dépendance spécifiée dans une option - mais nous devrions chercher à travailler pour la première fois dans autant de cas que possible, cela ne devrait donc pas être considéré comme la norme).
  • Je dirais que par défaut, l'approche devrait être de ne mettre à niveau que les dépendances qui doivent être mises à niveau pour satisfaire les nouvelles contraintes. Il y a un problème désagréable qui se cache ici, car les contraintes peuvent changer en fonction de ce qui est mis à niveau. Mais que nous fassions une solution complète à ce problème ou que nous essayions simplement une solution "au mieux" n'est pas si important (je doute que les graphiques de dépendance complexes avec des contraintes contradictoires soient courants dans la vie réelle). Le point important est le principe, que nous ne mettons pas à jour tout ce que l'utilisateur n'a pas demandé à être mis à jour, sauf si nous y sommes obligés.
  • Avoir un indicateur pour dire "tout mettre à niveau vers la dernière version" peut être utile (pour la compatibilité descendante, au moins). Encore mieux serait d'avoir des outils (probablement externes à pip) qui analysent et rendent compte des options de mise à niveau. Ensuite, les utilisateurs pourraient décider eux-mêmes. Mais je ne sais pas si je verrais un jour le besoin de l'une ou l'autre de ces options moi-même.
  • Plutôt qu'une option de "mise à niveau impatiente", je serais beaucoup plus susceptible de vouloir une commande upgrade-all (ou upgrade --all si nous voulons nous en tenir à une seule commande). Cela devrait être sémantiquement identique à upgrade avec chaque paquet installé répertorié sur la ligne de commande. Une fois que je fais des mises à niveau à l'aveugle de packages (généralement, je ne connais pas ou n'ai peut-être pas documenté l'arbre de dépendance de mes packages), je veux probablement juste "tout". Encore plus si j'utilise des environnements virtuels pour isoler les choses.
  • La question --only-binary apparaît à nouveau ici. Certes, si l'utilisateur spécifie --only-binary pour la mise à jour principale, les dépendances doivent être supposées impliquer --only-binary . Mais même si l'utilisateur autorise l'installation des sources lors de la mise à niveau du package principal, introduire le risque d'échec lié à la mise à niveau des sources d'une dépendance semble déraisonnable. Je suggère donc que nous ne devrions jamais considérer les binaires que pour la mise à niveau des dépendances, à moins que l'utilisateur n'autorise explicitement la source. Cela impliquerait d'avoir besoin d'une option --allow-source dep1,dep2,... . Je m'attends à ce que cette proposition soit controversée, mais considérons un package Python pur foo qui est distribué uniquement sous forme source, qui dépend de numpy. Nous avons foo 1.0 selon numpy >=1.10, et foo 2.0 selon numpy >=1.11. L'utilisateur a foo 1.0 et veut mettre à niveau. Ils n'ont pas les moyens de construire numpy. Ils doivent autoriser les mises à niveau des sources pour foo, mais ils ne veulent pas perdre de temps à essayer de construire numpy 1.11 (ou pire encore, le construire peut fonctionner mais donner une version non optimisée, ce qui casse leur système). Ils pourraient bien sûr spécifier --only-binary numpy mais ils peuvent même ne pas savoir que foo dépend de numpy.

C'est à peu près ça. Pour moi, les exigences sont assez claires (et honnêtement, je ne pense pas qu'elles soient particulièrement controversées si nous ignorons les problèmes de mise en œuvre). Cependant, la mise en œuvre est le tueur ici (essentiellement, ce qui précède exige à peu près une approche complète du solveur SAT, comme cela a été discuté précédemment). Quels compromis nous sommes prêts à faire parce que la mise en œuvre d'un solveur SAT est trop difficile, c'est là que se situeront probablement les débats.

Pour autant que je sache, les défis de mise en œuvre seront les suivants :

  1. Un solveur SAT complet est difficile. Je n'en sais pas assez pour comprendre quelles alternatives sont les plus simples et en quoi elles diffèrent d'un solveur SAT. (Eh bien, une mise à niveau impatiente est, je crois, assez simple - c'est pourquoi c'est ce que nous faisons en ce moment). Plus précisément, lorsque nous aurons une situation où nous mettrons à niveau quelque chose qui, selon le simple principe « ne mettez pas à niveau ce que vous n'êtes pas obligé de faire », dit qu'il n'aurait pas dû être mis à niveau.
  2. J'ai passé sous silence tout sauf les contraintes de dépendance les plus élémentaires. Une fois que nous sommes impliqués dans les limites supérieures des versions, ou les listes de versions autorisées, les choses se gâtent. Mais de manière réaliste, de tels cas sont susceptibles d'être assez rares (j'aimerais que quelqu'un fasse des recherches sur les informations de dépendance réelles de PyPI - je peux essayer de le faire, mais je doute d'avoir le temps).
  3. Lorsque nous avons plusieurs cibles - pip upgrade a b c - traitons-nous cela comme 3 actions distinctes, "mettre à niveau a", puis "mettre à niveau b" puis "mettre à niveau c", ou fusionnons-nous les 3 en un seul "combiné" action en quelque sorte (notez que parce que je propose de traiter les dépendances différemment des cibles, ce n'est _pas_ la même chose que pip upgrade dummy où dummy dépend de a, b et c et nous supposons que dummy a été mis à niveau).

Si quelqu'un veut contester l'un des commentaires ou affirmations ci-dessus, c'est parfait. La plupart de ceci n'est que mon opinion, et honnêtement, je ne travaille pas sur des environnements complexes - mon utilisation consistera probablement principalement à maintenir une installation système et quelques environnements virtuels sur Windows (par conséquent, les débats sur les installations binaires par rapport aux sources sont importants pour moi, mais pas tellement les graphiques de dépendance complexes). Plus il y a de cas d'utilisation contre lesquels nous pouvons vérifier nos hypothèses, mieux c'est.

Nous avons donc actuellement deux opérations, pip install et pip install --upgrade , mais je pense que ces deux choses font quelque chose que personne ne veut réellement arriver dans la vraie vie.

Pour pip install , nous obtenons ce genre de comportement étrange où vous pouvez obtenir la dernière version (ou pas !) En fonction de ce qui est déjà installé sur votre système. Je pense que ce genre d'étrangeté rend pip plus difficile à utiliser, et je ne pense pas que cela ait vraiment beaucoup de sens (dans quelle situation vous soucieriez-vous de ne pas mettre à niveau mais vous voulez toujours installer la dernière version si vous n'avez pas déjà ce?). Je pense que le fait que cette commande ait ce comportement étrange peut-être-le-dernier-peut-être-pas est la raison pour laquelle nous voyons beaucoup de gens atteindre pip install ---upgrade comme commande principale plutôt que pip install .

Cependant, pip install --upgrade n'est pas beaucoup mieux, bien qu'il vous donne un comportement cohérent, il est trop désireux, il s'étend à une mise à niveau complète de _everything_ dont l'utilisateur peut même ne pas savoir qu'il sera impliqué dans leur pip install --upgrade commande

Ce que je pense que nous devrions faire ici, c'est trouver un chemin pour faire `pip install ... more consistent. In that I mean pip install devrait toujours finir par avoir la dernière version acceptable (étant donné les spécificateurs et les indicateurs de modificateur comme--only-binary ``) indépendamment de ce qui a été précédemment installé.

Je pense que donner à cette commande une sorte de comportement --eager ou --recursive ou --upgrade-all-the-things serait bien.

Je ne pense pas qu'une commande pip upgrade qui prend une liste de packages soit quelque chose que nous devrions faire. Je pense que si nous ajoutons une telle commande, elle devrait être utilisée pour simplement mettre à niveau tout ce qui est installé vers les dernières versions (en tenant compte des informations de la chaîne de dépendance, ainsi que des modificateurs comme --only-binary ).

Hein? Donc pip install foo n'échoue pas toujours si foo est installé ? Cela me semble faux, je m'attendrais à ce qu'il dise simplement "déjà installé".

Je n'aime pas l'idée que pip install soit "installer ou mettre à niveau". Mieux vaut être explicite et tout ça.

À l'heure actuelle, pip install foo "échoue" jamais selon que quelque chose est installé ou non, il ne fera rien et dira que X est déjà installé. Mon affirmation est que le comportement n'est pas très utile. "Affirmer qu'une version, n'importe quelle version est installée" ne me semble pas être un comportement utile. Il ne correspond pas non plus aux autres gestionnaires de packages que j'ai l'habitude d'aimer apt-get ou plus.

OK, je peux voir que ce comportement n'est pas utile (bien que personnellement, je trouve qu'accepter silencieusement "déjà installé" comme assez inoffensif). Mais je préférerais voir l'installation d'un package déjà installé échouer, plutôt que de le mettre à niveau.

Qu'attendriez-vous de pip install foo-1.0-none-any.whl si foo 2.0 était déjà installé ? Rétrograder? Ne rien faire en silence ? Je préfère voir une simple erreur "déjà installée" plutôt qu'un ensemble complexe de règles dont je doute que les gens se souviennent dans la pratique.

Je n'ai pas beaucoup d'expérience avec les gestionnaires de packages Linux, je ne peux donc pas commenter les similitudes (ou autres) avec pip. Mais je ne pense pas que je m'attendrais à ce que apt-get install foo à niveau, donc si vous le dites, je ne peux que répondre que je trouverais cela étrange aussi.

"Affirmer qu'une version, n'importe quelle version est installée" ne me semble pas être un comportement utile.

Question secondaire rapide à ce sujet : qu'en est-il de « Assurez-vous que cette version spécifique est installée » ?

Peu importe, nous avons ce comportement aujourd'hui.

@pfmoore :

Qu'attendriez-vous de pip install foo-1.0-none-any.whl si foo 2.0 était déjà installé ? Rétrograder? Ne rien faire en silence ? Je préfère voir une simple erreur "déjà installée" plutôt qu'un ensemble complexe de règles dont je doute que les gens se souviennent dans la pratique.

Euh, les attentes sont des choses surprenantes. Je dirais que _évidemment_ dans ce cas, le pip devrait être déclassé. L'utilisateur a explicitement dit qu'il voulait que pip installe cette roue particulière, donc pip devrait installer cette roue particulière. Il n'y a rien de complexe là-dedans. Mais le cas "chemin/fichier de distribution est explicitement donné" est #536 -- nous devrions probablement garder cette discussion plus centrée sur ce qui se passe si l'utilisateur dit "pip install foo", qui va à l'index du paquet et trouve un foo 2.0, quand foo 1.0 est déjà installé.

Je suis tout à fait d'accord avec la position de Donald ici. Si nous partons de la question « que devrait faire pip install ? », alors je peux voir comment on pourrait affirmer que, eh bien, il est écrit « installer » dans le nom, donc il ne devrait installer que des choses, ne jamais les mettre à niveau ( enfin, sauf quand il y a quelque chose de contrainte). Mais si nous partons de la question « quelles opérations les utilisateurs veulent-ils ? », alors une commande qui pourrait installer la dernière version, ou pourrait vous laisser avec une ancienne version, est vraiment étrange et contre-intuitive. J'affirme que dans 99% des cas où les utilisateurs tapent pip install x , c'est parce qu'ils (a) ne savent pas s'il est installé ou savent qu'il ne l'est pas, ET (b) veulent s'assurer qu'ils l'ont installé car ils sont sur le point de commencer à l'utiliser pour la première fois. (Si ce n'était pas la première fois, ils sauraient qu'il a été installé, donc ils n'exécuteraient pas pip install .) Dans cette situation, leur donner la dernière version est la bonne chose à faire.

@chhammas :

Qu'en est-il de « Assurer que cette version spécifique est installée » ? Cela me semble utile, avoir une commande d'installation idempotente.

Pour "version spécifique", il y a pip install x==<version> .

Je peux aussi imaginer que pour certains types d'utilisation de scripts/programmatiques, il peut être utile d'avoir une commande pip require x qui a la même sémantique que l'installation d'un paquet avec Dist-Requires: x , c'est-à-dire qu'elle s'assure que certains version est installée mais sans aucune garantie sur quoi. Mais il s'agirait d'une commande de niveau inférieur non destinée aux utilisateurs finaux.

Une façon de penser à la différence entre ceux-ci : si x n'est pas installé, alors il serait acceptable pour pip require x d'installer une ancienne version aléatoire. (Et diable, peut-être devrait-il le faire, pour forcer les gens à être robustes contre cela .) Mais personne n'accepterait jamais pip install x installer une ancienne version aléatoire.

(Il s'agit d'une expérience de pensée, je ne préconise pas réellement que Dist-Requires: x ou pip require x dans un environnement sans x devraient choisir une ancienne version aléatoire de x à installer.)

Eh bien, je suppose qu'il y a aussi un autre cas où les utilisateurs tapent pip install x , c'est-à-dire quand ils savent déjà qu'il est installé, mais ils sont habitués aux systèmes avec le comportement de style Debian où install toujours mis à jour . Évidemment, ces utilisateurs veulent également qu'il soit mis à niveau :-).

Je préfère ne pas ajouter de commande pip upgrade .

Les utilisateurs de pip ont déjà des attentes quant au comportement de pip.
Le principal problème vient du comportement par défaut de pip instal --upgrade , alors concentrons-nous là-dessus.

Un avertissement dans le pip 9, plus des options supplémentaires pour modifier le comportement de pip install --upgrade , (--eager/non-eager) suivi dans le pip 10 par un changement de son comportement par défaut semble assez simple, devrait supprimer la douleur principale origine et ne casse pas le modèle mental des utilisateurs de pip de pip.

Oui, j'essaie vraiment d'aborder cela à partir de "quelles opérations un utilisateur veut-il faire" par rapport à "quelles opérations la commande X doit-elle faire". Je prends ensuite cette opération de haut niveau que je pense que les utilisateurs veulent faire et j'essaie de la mapper sur une seule commande nommée (aussi explicite que cela puisse être, pip install-the-latest-version`` n'est pas très convivial) .

Tout cela est évidemment très flou, mais je peux dire que 99% du temps, ce que je fais est pip install -U <whatever> car cela correspond le mieux à ce que j'attends d'un installateur compte tenu de ce qui est actuellement disponible. Je vois également dans divers scripts d'automatisation des personnes utilisant pip install -U . C'est aussi ce que font par défaut d'autres gestionnaires de packages populaires pour les langues, comme npm. Dans les cas où je vois des gens ne pas utiliser -U , c'est à cause de sa nature récursive, pas parce qu'ils ne veulent pas que la dernière version des choses soit installée.

Les utilisateurs de pip ont déjà des attentes quant au comportement de pip.

TBH, cependant, la principale attente que j'ai à propos de pip en tant qu'utilisateur est que sur environ 50% des invocations, il fera quelque chose de surprenant et manifestement faux. Et je ne suis pas le seul - voir par exemple la conférence de @glyph à pycon la semaine dernière où il a observé que pip est génial, sauf que toutes les valeurs par défaut sont cassées et nécessitent des drapeaux unbreak-me. Ce n'est pas une critique des développeurs pip, je comprends que vous/nous travaillons tous sous un ensemble complexe de contraintes, et ce n'est pas un argument selon lequel nous devrions juste casser les choses bon gré mal gré pour le plaisir de les casser -- pip a beaucoup de morceaux et beaucoup d'entre eux vont bien ! Mais étant donné l'état général des paramètres par défaut de pop, je ne suis _vraiment_ pas convaincu par les arguments de la forme "pip a toujours fait X, donc pip devrait toujours faire X". Si vous voulez plaider pour que pip install refuse la mise à niveau, c'est bien, mais je préférerais de loin voir cet argument fondé sur les mérites réels, pas seulement sur l'inertie.

Oui, je suis certainement d'accord avec @njsmith et @glyph ici. Nous avons un certain nombre de mauvais comportements par défaut, et une partie pour aller de l'avant, je pense, doit être de trouver comment nous pouvons nous en débarrasser et gérer ces changements de rupture pour faire avancer les choses vers de meilleurs paramètres par défaut.

Ce changement particulier n'en fait peut-être pas partie, mais je pense que oui.

Oui, j'essaie vraiment d'aborder cela à partir de "quelles opérations un utilisateur veut-il faire" par rapport à "quelles opérations la commande X doit-elle faire". Je prends ensuite cette opération de haut niveau que je pense que les utilisateurs veulent faire, et j'essaie de la mapper sur une seule commande nommée (aussi explicite que cela puisse être, pip install-the-latest-version`` n'est pas très convivial) .

D'ACCORD. Supposons que je sois prêt à me considérer comme convaincu (un peu) à ce sujet. Cependant, si nous supposons que c'est la bonne chose à faire, qu'en est-il des dépendances ? Je suis convaincu à 100% que "essayer d'installer numpy à partir des sources" n'est presque toujours pas ce que l'on veut. Nous n'installons donc numpy qu'à partir de roues, à moins que l'utilisateur ne mentionne explicitement numpy. Considérez cela comme un acquis pour le moment, puis supposons que nous ayons la situation que j'ai décrite plus tôt.

  • L'utilisateur a installé foo 1.0 et numpy 1.10, foo 1.0 dépend de numpy >= 1.10
  • PyPI a foo 2.0 disponible, dépend de numpy >= 1.11. Il n'y a pas de roues numpy 1.11.

Que fait pip install foo ? Vraisemblablement laisser l'utilisateur à 1.0, car c'est une installation qui fonctionne ? Mais devrait-il réussir (car foo est installé) ou échouer (car il n'a pas pu installer la dernière version) ? Dans le premier cas, comment l'utilisateur découvre-t-il que son système est obsolète ? Dans ce dernier cas, comment l'utilisateur dit-il « Je veux juste m'assurer que foo est là » ? OK, l'utilisateur peut faire pip list --outdated , voir que foo 2.0 existe et faire pip install foo (BTW, ça me semble toujours complètement bizarre, j'ai foo, mais je sais qu'il y a une nouvelle version, donc Je fais pip install??? Nevermind...) Et obtenir un succès, mais 1.0 reste installé?

L'une des raisons pour lesquelles je préfère deux commandes est que l'intention de l'utilisateur est parfaitement claire, de sorte que les cas extrêmes comme celui-ci peuvent être traités correctement car nous connaissons les attentes de l'utilisateur.

Peut-être que tout cela est évident si vous êtes habitué à apt-get. Mais je peux certainement dire que ce n'est pas du tout clair pour quelqu'un comme moi qui ne l'est pas.

Si vous voulez plaider pour que pip install refuse la mise à niveau, c'est bien, mais je préférerais de loin voir cet argument fondé sur les mérites réels, pas seulement sur l'inertie.

Mon argumentation repose sur l'explicite plutôt que sur l'implicite. Très certainement _pas_ sur "nous l'avons toujours fait de cette façon". Je n'ai aucun problème avec l'idée que les utilisateurs apt sont peut-être habitués à "installer" ce qui signifie "éventuellement mettre à niveau". Je ne suis vraiment pas si sûr que d'autres utilisateurs le seraient.

Une pensée - apt a-t-il un "package existe déjà - mise à niveau?" rapide? Je pourrais imaginer que l'installation en tant que mise à niveau me surprend moins si c'était "installer-ou-demander-si-je-devrais-mettre à niveau"... Bien sûr, pip ne se comporte pas comme ça de manière interactive pour le moment, bien que évidemment le faire faire est une option.

C'est une question intéressante -- les autres gestionnaires de paquets contournent ce problème soit en n'ayant pas vraiment de paquets binaires du tout donc c'est _toujours_ par source, soit en traitant à peu près uniquement des paquets binaires donc c'est _toujours_ binaire. Nous sommes dans une sorte de bizarrerie entre les deux, ce qui rend les choses plus difficiles.

Compte tenu de cela, je pense que par défaut pour le moment, nous devrions extraire le paquet source numpy 1.11 et essayer de l'installer, mais s'ils ont spécifié --only-binary , alors notre hypothétique résolveur (dont nous avons désespérément besoin, SAT ou suivi de retour ou autre) verrait que foo-2.0 n'est pas une installation résolvable et reviendra alors à l'installation de foo-1.0 . Ce n'est pas une valeur par défaut, en particulier pour les utilisateurs de Windows où la compilation est _beaucoup_ plus difficile, mais je pense que cela reflète la réalité d'aujourd'hui.

Cela étant dit, une chose que je veux vraiment faire est de commencer à essayer de pousser les choses vers un monde où nous pouvons à nouveau modifier le comportement de pip afin que par défaut nous puissions être uniquement binaires et exiger l'inscription pour les versions source, mais je ne pensez pas que nous sommes encore à un endroit où nous pouvons le faire.

@pfmoore : Je pense que la question des installations binaires par rapport aux sources est quelque peu orthogonale ? Il me semble que les mêmes questions se posent pour une commande dédiée pip upgrade , alors même s'il s'agit de vrais problèmes que nous devons résoudre, diviser la mise à niveau et l'installation ne fait que déplacer les problèmes plutôt que de les simplifier ? De plus, dans le cas particulier de numpy, nous expédions désormais des roues pour pratiquement toutes les plates-formes que nous nous soucions de prendre en charge :-).

Mais voici comment je suggérerais de gérer ces problèmes pour pip install foo (en particulier cette commande -- je ne parle pas de pip install foo==whatever ou pip install ./foo-*.whl ou pip install barbar a Requires-Dist: foo ):

1) Interrogez l'index pour trouver la dernière version candidate de foo ; appelez ça $LATEST . S'il n'existe aucune version candidate, une erreur est générée.

2) Si $LATEST est déjà installé, alors terminez avec succès.

3) Vérifiez s'il existe une distribution de $LATEST qui peut être installée sur l'environnement actuel. (Exemple de raisons pour lesquelles il pourrait ne pas y en avoir : il n'y a que des roues, mais pas de sdist, et les roues ne correspondent pas à l'environnement actuel. Il n'y a pas de roue correspondante et il y a une sdist, mais l'utilisateur a passé --binary-only :all: . Il n'y a pas de roue correspondante, et il y a un sdist, mais le sdist a un indicateur disant "Je ne travaille que sur python 3" et l'utilisateur exécute python 2 -- les gens ipython/jupyter le feront probablement proposer cela comme nouvelle fonctionnalité bientôt, car ils souhaitent abandonner la prise en charge de python 2 pour les nouvelles versions en janvier tout en fournissant un LTS prenant en charge python-2.)

4) Si $LATEST _n'a pas_ de distribution viable : émettre un avertissement pour indiquer à l'utilisateur qu'une version plus récente est disponible mais pas pour son environnement, idéalement avec un indice sur ce qu'il doit faire s'il le fait vraiment voulez la nouvelle version (par exemple, "ipython 6.0.1 est disponible mais nécessite python >= 3.4, et vous avez python 2.7 -- envisagez de mettre à niveau python", ou "numpy 1.12 est disponible, mais il n'y a pas de binaire pour ppc64 et vous avez construction désactivée à partir des sources - considérez --allow-source numpy ). Ensuite, supprimez $LATEST de la liste des versions candidates et passez à l'étape 1.

5) Si $LATEST _a une distribution viable, essayez d'installer cette distribution.

6) Si l'installation échoue (par exemple, c'est un sdist et il n'y a pas de compilateur), alors erreur. Sinon, terminez avec succès.

@njsmith binaire uniquement est quelque peu orthogonal, d'accord, mais l'OMI si nous essayons de concevoir des commandes qui "font ce que l'utilisateur attend", alors il est essentiel de bien faire les choses en même temps.

@dstufft le problème avec "installer numpy sauf si l'utilisateur dit que --binary-only été expliqué dans l'exemple de mon précédent article épique - (1) dire que foo n'est disponible que sous forme source, et (2) l'utilisateur ne peut pas (et en effet ne devrait pas avoir besoin de savoir que foo dépend de numpy. Ensuite, l'utilisateur ne peut pas dire --only-binary :all: et n'a aucune idée qu'il a besoin de --only-binary numpy jusqu'à _après_ un (long) échec de compilation. Ou (peut-être pire encore) une compilation réussie qui laisse à l'utilisateur un numpy non optimisé (de nos jours, numpy compile prêt à l'emploi sous Windows, mais donne une version non optimisée).

Je suis tout à fait d'accord qu'à long terme, nous devrions utiliser par défaut uniquement le binaire, mais nous n'en sommes pas encore là (au minimum, cela devrait impliquer que pratiquement tous les packages de python pur sont disponibles sous forme de roue).

@pradyunsg Comme vous pouvez le voir, il y a encore beaucoup de problèmes non résolus ici. Êtes-vous toujours intéressé à faire avancer cela? Je suis réticent à lancer un autre long débat s'il doit à nouveau caler...

@pradyunsg Comme vous pouvez le voir, il y a encore beaucoup de problèmes non résolus ici. Êtes-vous toujours intéressé à faire avancer cela? Je suis réticent à lancer un autre long débat s'il doit à nouveau caler...

Je m'y attendais. Je suis intéressé à faire avancer cela. Faisons cela! :le sourire:

Je suggère de collecter une liste avec tout ce qu'un _utilisateur_ veut que pip fasse, puis de proposer des solutions pour chacun d'eux jusqu'à ce que tous (ou un nombre suffisant) d'entre eux soient résolus par une commande pip (avec options/valeurs par défaut) ou puissent être gérés avec "pas d'action".

Pour commencer, voici une liste probablement incomplète :

  1. Un utilisateur souhaite installer un package qui n'est pas encore installé.
  2. Un utilisateur tente d'installer un package déjà installé.
  3. Un utilisateur souhaite mettre à niveau un package installé.
  4. Un utilisateur tente de mettre à niveau un package qui n'est pas installé.
  5. Un utilisateur veut s'assurer qu'il a installé la dernière version d'un package, qu'il soit déjà installé ou non.
  6. Un utilisateur ne souhaite généralement pas que toutes les dépendances soient mises à niveau et qu'elles soient uniquement satisfaites.
  7. Un utilisateur souhaite mettre à niveau/installer un package mais ne souhaite pas compiler à partir des sources (ni le package ni ses dépendances). Probablement plus probable que :
  8. Un utilisateur est prêt à mettre à niveau/installer à partir de la source.

Mes propositions personnelles pour cela, en tant qu'utilisateur :

1) & 7) pip install foo doit essayer de résoudre la dernière version disponible (en tenant compte des dépendances) et l'installer. L'algorithme serait celui de @njsmith .
2) pip install foo → affiche un avertissement indiquant que foo est déjà installé et propose d'utiliser pip upgrade foo
3) & 7) pip upgrade foo tente d'installer la dernière version disponible de foo, encore une fois en suivant l'algorithme de @njsmith . Si une version plus récente ne peut pas être installée parce qu'elle n'est pas disponible pour la plate-forme et qu'il n'y a pas de sdist ou que l'utilisateur ne veut pas construire à partir des sources, montrez-le. Réussir dans les deux cas et échouer uniquement si l'installation elle-même a échoué.
4) pip upgrade foo échoue si le package n'est pas installé.
5) pip install-uprade foo ou pip install foo --ensure-latest ou pip install foo --upgrade (essentiellement le même qu'actuellement sauf non désireux).
7) Toutes les opérations ne devraient pas être impatientes et un indicateur --eager serait disponible pour obtenir l'ancienne fonctionnalité de install --upgrade . Si une dépendance n'est pas encore installée, installez la dernière. S'il est déjà satisfait, ne faites rien. S'il n'est pas satisfait, installez la dernière version toujours satisfaisante (pour les exigences de la limite supérieure).
8) pip upgrade foo --allow-source ou pip upgrade foo --allow-source numpy , si foo dépend des versions numpy non binaires. Edit: Je ne sais pas si cela serait applicable, voir le commentaire ci-dessous.

N'hésitez pas à allonger la liste et à poster vos propres propositions.

@pfmoore, je ne sais pas quelle est l'alternative? L'état du monde aujourd'hui est que les roues gagnent du terrain, mais elles sont loin d'être omniprésentes, donc je ne suis pas sûr de voir vraiment une bonne option qui n'autorise pas les versions de source par défaut pour le moment.

@dstufft ma proposition était d'autoriser la source pour les packages nommés explicitement, mais par défaut uniquement les binaires pour les dépendances. De cette façon, l'utilisateur n'obtient aucune étape de construction « surprise ». C'est un compromis, bien sûr, mais cela reflète ce que je (dois) faire manuellement pour le moment.

@FichteFoll Avant tout, mon cas d'utilisation principal concerne une capacité de "tout mettre à niveau". Recherchez tout ce qui est actuellement installé et s'il existe des versions plus récentes, mettez-les à niveau.

Les packages que j'ai installés n'ont généralement rien d'autre que des dépendances ">=" (et la plupart n'en ont même pas) donc il n'y a rien de complexe ici. Prenez simplement la dernière version. Ma plus grande restriction est qu'il y a certains packages que je ne peux pas construire (numpy, scipy, lxml, pyyaml, matplotlib, pyqt), donc je ne veux que des binaires pour ceux-ci. Je peux probablement juste mettre --only-binary <these> dans mon pip.ini (ou du moins j'espère que je peux...)

Secondaire : installez le package XXX (dernière version), ainsi que toutes ses dépendances que je n'ai pas déjà. Ne mettez pas à niveau les dépendances que j'ai déjà si elles satisfont aux contraintes du nouveau package. Je sais toujours que je n'ai pas XXX actuellement.

Tertiaire : mettre à niveau un seul package XXX que j'ai (je sais que j'ai) installé. Ne modifiez aucun autre package à moins que cela ne soit nécessaire pour maintenir des contraintes de dépendance (et même cela est théorique - je n'ai jamais rencontré la situation dans la vraie vie, donc je ne sais pas quelle serait la meilleure résolution pour moi). Mon intention est toujours de "mettre à niveau vers la dernière version". Je n'ai jamais rencontré de situation où cela briserait les dépendances des packages déjà installés. Si c'est le cas, je pense que j'aimerais être averti que je n'ai pas reçu la dernière version (et pourquoi) ainsi qu'une mise à niveau vers la dernière version acceptable. Dans mon esprit, cette situation se traduit actuellement par pip install -U bien que le comportement des dépendances ne soit pas ce que je veux. La principale raison pour laquelle je ferais cela est l'absence actuelle d'un "mettre à niveau tout" approprié (ou pour traiter les cas où une nouvelle commande "mettre à niveau tout" n'a pas fonctionné comme je le voulais).

Toute la discussion sur les dépendances et les contraintes est, d'après mon expérience, presque entièrement théorique. J'ai actuellement 160 packages installés dans mon système Python (un mélange de modules scientifiques, d'analyse de données, Web et de programmation générale). 100 d'entre eux n'ont aucune exigence. Pour le reste, aucun n'a rien de plus complexe qu'une liste de packages - aucune contrainte de version ou quelque chose de plus complexe que Requires: six, dask, pillow, networkx . La plus longue liste de dépendances comportait 9 éléments.

@pfmoore Est-ce que ça ne va pas casser beaucoup de choses ? Une liste rapide de choses auxquelles je peux penser du haut de ma tête et que je sais être des packages très populaires dépend de tout :

  • SQLAlchemy (nécessite éventuellement un compilateur, utilisera du Python pur sinon).
  • PyYAML (nécessite éventuellement un compilateur, utilisera du Python pur sinon).
  • Markupsafe (nécessite éventuellement un compilateur, utilisera du Python pur sinon).
  • PyCrypto (nécessite toujours un compilateur)
  • pycparser (ne nécessite jamais de compilateur)
  • httplib2 (ne nécessite jamais de compilateur)
  • anyjson (ne nécessite jamais de compilateur)
  • zope.interface (nécessite éventuellement un compilateur, utilisera Pure Python sinon).
  • docopt (ne nécessite jamais de compilateur)
  • Mako (ne nécessite jamais de compilateur)
  • c'est dangereux (ne nécessite jamais de compilateur)
  • amqp (ne nécessite jamais de compilateur)
  • orderdict (ne nécessite jamais de compilateur)

et ainsi de suite, vous pouvez voir une longue liste des packages les plus populaires et s'ils ont ou non des roues sur http://pythonwheels.com/.

@pfmoore

Recherchez tout ce qui est actuellement installé et s'il existe des versions plus récentes, mettez-les à niveau.

J'ai trouvé cette commande à partir d'une question SO il y a quelque temps que j'utilise actuellement pour cela. C'est sous-optimal, mais fonctionne pour la plupart de mes packages, sauf un. (Il utilise le lanceur py car je suis sous Windows.)

pip list -o | cut -d " " -f 1 | xargs -n1 py -m pip install -U

Maintenant, le seul problème que j'ai avec ceci est le paquet flake8, qui a ces exigences :

Requires-Dist: pyflakes (>=0.8.1,<1.1)
Requires-Dist: pep8 (>=1.5.7,!=1.6.0,!=1.6.1,!=1.6.2)
Requires-Dist: mccabe (>=0.2.1,<0.5)

Plus précisément, pyflakes est un problème car une version plus récente est disponible et est mise à jour avec la commande ci-dessus, ce qui fait que flake8 échoue à faire quoi que ce soit (puisqu'il vérifie la version).
C'est donc en effet quelque chose qui doit être pris en compte et j'aimerais également disposer d'une fonctionnalité de mise à niveau complète (sans casser les exigences !).

@dstufft pourquoi ? Si foo dépend de pyyaml ​​et que je demande de mettre à niveau foo, pyyaml ​​n'est pas mis à jour (pas de nouveaux binaires) mais foo peut toujours être mis à niveau, car il y a toujours le pyyaml ​​d'origine présent.

Pour les nouvelles dépendances (ou lors de l'installation où une dépendance n'est pas toujours présente), vous devez installer, donc s'il n'y a pas de binaire, vous prenez la source. Personnellement, je considérerais "choisir l'ancienne version avec le binaire plutôt que la nouvelle version avec la source", mais cela se rapproche dangereusement de la valeur par défaut de --binary-only laquelle je conviens que nous ne sommes pas prêts.

Hmm, peut-être que le problème que j'ai est en fait avec l'option --only-binary , qui est trop grossière. Si nous avions une option --prefer-binary , qui disait "N'utilisez que des binaires, à moins que cela signifie qu'il n'y a pas de candidats, auquel cas réessayez d'autoriser la source", je soupçonne bon nombre de mes inquiétudes qu'une mise à niveau trop rapide entraînerait une rupture pourrait être allégé. Ce qui, comme @njsmith l'a suggéré, signifie que les distinctions binaire/source sur lesquelles je me concentre pourraient bien être orthogonales à ce ticket (bien que cela changerait simplement ma position en "il n'y a pas de solution satisfaisante à mes besoins sans quelque chose de mieux que --only-binary étant disponible"...).

Spécifiquement pyflakes est un problème

OK, donc ce n'est pas une situation que j'ai (comme je l'ai dit, je n'ai rien avec des dépendances aussi complexes installées). Je n'ai pas de problème à affiner "tout mettre à niveau" pour mettre à niveau les choses vers "la dernière version qui n'entraîne pas de casse", mais AIUI qui a besoin de l'approche "résolveur SAT" pour trouver la bonne solution. C'est cependant un problème d'implémentation - la conception doit en effet toujours donner des résultats corrects.

@pfmoore Je pense qu'un drapeau --prefer-binary pourrait être une bonne option, quel que soit le résultat de ce ticket. Probablement accompagné d'un avertissement lorsque cela finit par ne pas installer la dernière version qui aurait autrement été installée.

@FicheFoll : Je ne pense pas qu'essayer de reconstituer l'ensemble de l'interface utilisateur à partir des premiers principes sera très productif. Il y a un élément du problème relativement clairement défini qui est en rapport avec ce problème particulier, et si nous essayons d'étendre la portée à tout à la fois, cela s'enlisera à nouveau.

Sur ce sujet, il semble que le point clé sur lequel nous différons est celui-ci : supposons qu'un utilisateur ait le modèle mental que pip install foo ne sert qu'à faire passer les choses de désinstallé à installé, et qu'il comprenne que foo est déjà installé. J'affirme qu'un utilisateur avec ce modèle mental _ne tapera jamais pip install foo _. Par conséquent, lorsqu'un utilisateur _fait_ taper pip install foo alors que foo est déjà installé, nous pouvons conclure que son modèle mental n'est pas comme le vôtre (2). _Soit_ la première partie est fausse : ils savent que foo est installé et ils s'attendent à ce que pip soit mis à niveau comme certains autres gestionnaires de paquets populaires, _ou_, la deuxième partie est fausse : ils ne savent pas que foo est installé , auquel cas ils s'attendent install ce que

Pour mémoire, l'une des raisons pour lesquelles je n'aime pas le pip install ... ne passe que de désinstallé à installé et pip upgrade ... ne passe que d'installé à un élément plus récent installé est parce que je trouve l'utilisateur expérience assez minable. Un logiciel qui sait ce que vous vouliez qu'il fasse, mais au lieu de faire cette chose, il vous dit d'invoquer une commande différente est incroyablement frustrant.

$ pip install foobar
I'm sorry, but foobar is already installed, you want to run ``pip upgrade foobar``
$ pip upgrade foobar
...

Ne ferait rien pour moi à part m'ennuyer, même si c'est techniquement "correct".

Le revers de la médaille, si vous dites "ok, si pip install foobar déjà foobar installé, alors nous agirons comme s'il n'était pas installé, et si vous faites pip upgrade foobar alors nous 'agira comme si elle était déjà installée, nous nous retrouvons avec deux commandes qui font fondamentalement la même chose, sauf avec _peut-être_ quelques différences mineures dans la façon dont les choses sont traitées, ce qui me dit qu'elles appartiennent en tant que commande singulière avec quelque --options pour gérer les cas extrêmes. Je pense que c'est mieux parce que cela signifie que les utilisateurs n'ont pas à essayer de faire un choix entre celui qu'ils veulent à l'avance, il y a une commande pour installer des trucs et pour la plupart des utilisateurs qui le feront Si un utilisateur dans un scénario spécifique nécessite des choix de sa part, il doit alors payer le coût de certains choix sur les --flags à utiliser.

D'ACCORD. Considérez-moi convaincu. J'ai fait quelques recherches, et même les installateurs Windows que je connais (soi-disant :-)) font install-as-upgrade (si vous installez quelque chose comme VirtualBox, il dit "vous avez déjà une version précédente installée, voulez-vous voulez-vous mettre à niveau ?") Powershell a un package d'installation, qui ne dit rien de spécifique, mais il n'y a pas de package de mise à niveau. Etc. Donc, je suppose que le simple fait d'avoir la seule commande "install" est la norme.

Ce qui bien sûr signifie que, à moins que quelqu'un d'autre ne veuille discuter, techniquement, ce PR peut simplement être clôturé comme "ne va pas être mis en œuvre". Mais c'est toujours un bon endroit pour discuter de _comment_ nous voulons remodeler la commande d'installation, je suppose.

OTOH, peut-être que nous fermons ceci comme rejeté, et que quelqu'un ouvre un nouveau problème, avec une proposition concrète sur la façon dont ils suggèrent que la commande d'installation doit être modifiée. Cela pourrait au moins fournir un point de départ plus clair pour les discussions.

Une question. Est-ce que quelqu'un pense que nous sommes encore à un point où quelqu'un pourrait élaborer un comportement proposé complet à partir de toutes les suggestions ici et ailleurs ? Couvrant la manière dont les dépendances sont gérées, que se passe-t-il avec les contraintes (et quand elles sont en conflit), binaire vs source, comment prenons-nous en charge le scénario « tout mettre à niveau », etc ? Mon sentiment personnel est que nous avons besoin de quelqu'un pour prendre cette décision, pour donner à la discussion un point de référence, ou nous pourrions simplement débattre des détails pour toujours. Je pourrais probablement le faire, mais il est peu probable que je puisse mettre en œuvre ce que je propose (par exemple, je proposerais une approche de "résolution optimale des dépendances", ce qui implique un solveur SAT AIUI). Il serait donc préférable pour quelqu'un qui est prêt à mettre en œuvre sa proposition d'intensifier (et de faire face à l'inévitable débat et au bikeshedding :-)).

Je suis toujours préoccupé par certaines des implications des points soulevés ici, mais je ne suis pas sûr d'avoir l'énergie d'en débattre jusqu'à ce qu'il y ait une réelle possibilité de mise en œuvre.

Je suis entièrement d' accord avec @dstufft « s dernière https://github.com/pypa/pip/issues/59#issuecomment -224341218
C'est pourquoi (encore une fois) je préconiserais la solution simple des options --eager / --non-eager .

Je suis également d'accord avec le commentaire de @dstufft , comme indiqué (nous install et aucune commande update ).

Cependant, je ne suis pas sûr de ce que --eager / --non-eager implique. Je suppose que --non-eager signifie ne pas mettre à niveau tout ce qui n'a pas besoin d'être mis à jour (soit parce que l'utilisateur l'a spécifié explicitement, soit parce qu'il est trop ancien pour satisfaire le nouvel ensemble de dépendances). Est-ce que --eager signifie alors mettre à niveau chaque dépendance vers la dernière version possible, que ce soit nécessaire ou non ? Quelle serait la valeur par défaut ? (Je dirais --non-eager )

Et une question : cela encouragerait-il les packages scientifiques à déclarer correctement leurs dépendances ? Cela doit être une considération importante.

Point de remise à vélo. Les noms d'options --eager et --non-eager sont assez peu intuitifs. Je pense que nous avons besoin de meilleures conditions. Peut-être quelque chose d'explicite comme --upgrade-dependencies .

Ce PR suggère également une commande upgrade-all , qui est le cas d'utilisation clé pour moi. Êtes-vous en train de dire que nous rejetons cette commande, ou simplement que vous n'avez pas d'opinion là-dessus ?

Ma compréhension de ce que signifie --eager et -non-eager correspond à ce que @pfmoore vient de dire (que les dépendances soient uniquement si nécessaires ou toujours installées), et je suis d'accord que --non-eager devrait être le défaut. Je suis également d'accord que le nom est un peu minable bien que je n'ai pas de meilleure solution qui ne soit pas une bouchée. Peut-être --[no-]recursive ou quelque chose, je ne sais pas.

Je pense que quelque chose comme une commande upgrade-all pourrait être un bon ajout (tant qu'il s'assure de ne pas violer les spécificateurs de version de quoi que ce soit). J'appellerais probablement cela upgrade et ne laisserais aucun argument pour restreindre ce sur quoi il opère.

tl; dr
Discussion pour un upgrade-all-packages - reste ici.
Discussion pour prefer-binary - Passez au #3785
Discussion pour l'installation en tant que mise à niveau - Passez au #3786


Si nous avions une option --prefer-binary, qui disait "n'utilisez que des binaires, à moins que cela signifie qu'il n'y a pas de candidats, auquel cas réessayez d'autoriser la source"

C'est une bonne idée. Bien que lié à ce problème, je pense qu'il mérite son propre problème. (Le commentaire de @dstufft me fait penser qu'il y a un intérêt à le poursuivre). J'ai pris la liberté d'ouvrir le #3785 pour une discussion plus approfondie à ce sujet.

Ma compréhension de ce que --eager et -non-eager signifient correspond à ce que @pfmoore vient de dire (que les dépendances soient uniquement si nécessaires ou toujours installées)

Une mise à niveau impatiente installerait les dernières versions autorisées de toutes les (sous-) dépendances.

Les noms d'options --eager et --non-eager sont assez peu intuitifs.

Je suis d'accord. J'aime l'idée de mettre le comportement derrière un seul drapeau.
--upgrade-strategy=eager/non-eager

C'est une bouchée aussi, mais cela exprime l'intention de manière plus explicite. C'est trop verbeux ? Peut-être.

Je pense que le bike-shedding est mieux fait après avoir finalisé la sémantique.

Est-ce que quelqu'un pense que nous sommes encore à un point où quelqu'un pourrait élaborer un comportement proposé complet à partir de toutes les suggestions ici et ailleurs ?

Je le pense. Nous devons au moins établir des faits de base sur lesquels nous sommes d'accord. Je suis sur ça.

OTOH, peut-être que nous fermons ceci comme rejeté, et que quelqu'un ouvre un nouveau problème, avec une proposition concrète sur la façon dont ils suggèrent que la commande d'installation doit être modifiée. Cela pourrait au moins fournir un point de départ plus clair pour les discussions.

Je pense que nous devrions laisser ce problème ouvert pour le moment, car il propose un upgrade-all . Vous avez déjà noté que la mise à niveau ne se produit pas. J'ai ouvert #3786 pour une discussion ultérieure sur la commande install-as-upgrade.

Je suis toujours préoccupé par certaines des implications des points soulevés ici, mais je ne suis pas sûr d'avoir l'énergie d'en débattre jusqu'à ce qu'il y ait une réelle possibilité de mise en œuvre.

Je suis prêt à aller de l'avant jusqu'à la mise en œuvre. Je ne veux certainement pas gaspiller les efforts de tout le monde pour parvenir à un consensus à ce sujet.

Je pense que tout le monde est d'accord sur le fait qu'une commande "mettre à niveau le monde" serait vraiment bien, mais IIUC est bloqué pendant que nous attendons que le résolveur atterrisse. En attendant, j'ai posté une proposition plus concrète de mises à @pradyunsg pour cette discussion.

Je pense que tout le monde est d'accord sur le fait qu'une commande "mettre à niveau le monde" serait vraiment bien, mais IIUC est bloqué pendant que nous attendons que le résolveur atterrisse.

En effet, ce problème est désormais correctement bloqué par le #988. Mentionner le numéro du problème pour lier les deux problèmes.

J'ai presque oublié...

Je ne sais pas ce que vous entendez par "conserver" les mises à jour. Précisez s'il vous plaît.

Maintenant que ce problème concerne exclusivement la mise à niveau, je dois clarifier.

Dans certaines situations, il peut être utile d'empêcher la mise à niveau d'un certain package lorsque nous exécutons upgrade-all. Celui que j'ai en tête est... Si pkg est installé et que je ne veux pas m'embêter à reconfigurer une version potentielle plus récente, je veux donc empêcher pip de mettre à niveau ce package spécifique lors de l'exécution de 'mettre à niveau le monde'. Essentiellement, je retiens la mise à niveau de pkg.

Un indicateur qui prend une liste de packages séparés par des virgules à retenir d'une mise à niveau conviendrait.

L'ajouter une fois qu'un solveur SAT arrive devrait être facile. C'est juste quelques clauses supplémentaires IIUC. (Oui, je me penche également sur les solveurs SAT)

Je ne sais pas si c'est quelque chose de commun ou quelque chose que quelqu'un veut. Mais je ne pense pas que cela vienne de ma tête. Quelqu'un doit l'avoir mentionné dans un fil quelque part.

Ah, je vois. Cela a du sens et semble être une chose raisonnable à vouloir.

Demande rapide : quelqu'un pourrait-il ajouter à la description une petite note indiquant que la commande de mise à niveau ne se produira pas ? Si vous le souhaitez, écrivez éventuellement un petit résumé expliquant pourquoi il en est ainsi.

_va dormir_

Deux fonctionnalités intéressantes d'apt (et je pense que d'autres gestionnaires de packages système matures comme dnf ont des fonctionnalités similaires):

  • Marquer un paquet comme "tenu", qui est un indicateur persistant attaché au paquet et le fait sauter par les commandes upgrade-the-world. Souvent défini sur des packages que vous deviez rétrograder ou patcher localement.
  • Suivi des packages explicitement demandés par l'utilisateur, par rapport à ceux qui n'ont été installés que implicitement pour répondre aux contraintes de dépendance. Ces derniers peuvent être supprimés par une mise à niveau du monde s'ils cessent d'être dépendants.

Les deux peuvent être considérés comme des cas particuliers de ce que font les gestionnaires de packages d'environnement de projet plus récents comme npm et cargo, où ils font la distinction entre une sorte de fichier d'"exigences" orienté vers l'homme et un fichier de "verrouillage" entièrement spécifié. Un package détenu explicitement est comme un package qui a une contrainte de version spécifiée par l'homme, et un package explicitement installé est celui qui est répertorié dans le fichier modifiable par l'homme.

Idem. Si nous ajoutons "mettre à niveau le monde", nous devons ajouter la possibilité de marquer les packages (comme held / user-installed et peut-être plus) pour ajouter des informations afin de mieux déterminer un plan d'action pour les mises à niveau. Je vois cela comme une exigence, pas comme un plaisir à avoir.

En fait, j'aime la technique utilisée par Cargo et j'aime. L'utilisation de fichiers et non d'une forme de méta-données cachées derrière une commande cli rend beaucoup plus facile à saisir, à gérer et permet également de créer un environnement reproductible.

En fait, je serais heureux si je voyais une forme de pyproject.lock ...

200e commentaire. Wow. :souriant:

Ajout d'une référence à #654 pour le "marquage" des packages dont nous avons parlé.

Pouvez-vous expliquer ce que fait la cargaison? Où verriez-vous le fichier pyproject.lock stocké sur la machine de l'utilisateur ?

Le fichier de verrouillage de Rust's Cargo est stocké à la racine du projet, pour enregistrer la version des dépendances actuellement installées. La validation de ce fichier dans git vous permet de partager un ensemble cohérent de versions de dépendances avec d'autres développeurs et CI. Composer de PHP a un fichier de verrouillage similaire, Composer.lock.

J'ai toujours supposé que "pip freeze" et "pip install -r" de pip étaient censés faire la même chose, et il était juste regrettable que le format de fichier de verrouillage soit facilement lisible/inscriptible par les humains et que les gens choisissent de le modifier directement. Le fichier requirements.txt n'a-t-il pas été conçu à l'origine comme un fichier de verrouillage ?

@triplepoint Merci pour l'explication. Cela ressemble en effet plus à un fichier d'exigences. Mais les fichiers d'exigences sont facultatifs, basés sur la version et par projet. Le marquage (si je comprends bien) doit être par environnement (virtualenv ou installation système) et doit simplement dire "ne pas mettre à niveau automatiquement le package X" (mais autoriser la mise à niveau manuelle si l'utilisateur demande explicitement une mise à niveau de ce package par nom).

Pour aider à démêler les discussions sur upgrade-all et "comportement de mise à niveau", voici les commentaires de @rbtcollins et @ncoghlan dans la discussion sur la liste sur ce dernier à propos d'un solveur SAT n'étant pas requis pour une première implémentation de upgrade-all :

Robert :

Je me rends compte que le consensus sur le ticket est qu'il est bloqué, mais je ne le fais pas
en fait d'accord.

Oui, vous ne pouvez pas le faire _correctement_ sans un résolveur complet, mais vous pouvez le faire
une approximation qui serait bien mieux que rien (juste étroit
les spécificateurs donnés pour toutes les exigences). C'est en fait
raisonnable lorsque vous avez affaire à un ensemble présumé de bonnes versions
(dont l'installation ne traite pas).

Pseudo:

"yum upgrade" a assez bien fonctionné pendant des années sans un solveur SAT approprié, et le package défini dans une installation Linux typique est beaucoup plus volumineux que celui d'un environnement virtuel typique (bien que la distribution réduise le risque de conflits d'exigences survenant dans le premier lieu).

Cela dit, réexécuter pip-compile puis effectuer une pip-sync est déjà un équivalent fonctionnel d'une opération de mise à niveau globale (comme détruire et recréer un venv), donc je suis d'accord qu'il n'est pas nécessaire de coupler la question de la prise en charge des mises à niveau en masse dans pip de base avec la modification du comportement de la mise à niveau des composants nommés.

OMI, pip upgrade-all est de loin la proposition la plus importante sur la table parmi toutes les différentes discussions sur les "fonctionnalités de mise à niveau". Avoir "tout mettre à niveau" donnerait un moyen évident de maintenir votre système à jour, ce qui rendrait les questions sur les mises à jour non désireuses, laissant les choses aux niveaux plus anciens beaucoup moins urgentes, tout en comblant une lacune qui existe actuellement.

Bien qu'un solveur complet serait bien, je ne vois aucune raison pour laquelle le point de départ de pip upgrade-all ne devrait pas être qu'il fait ce que fait pip install -U <list every package that's installed here> . C'est ce à quoi je m'attendrais en tant qu'utilisateur, et dans la majorité des cas, il fait exactement ce qui est nécessaire. Les cas complexes autour d'exigences contradictoires peuvent être traités en premier lieu en se référant à ce qui précède. Si cela ne suffit pas, nous pouvons envisager de modifier le comportement de install -U pour y remédier, ou de mettre en casse spéciale la commande update-all , ou même d'implémenter un solveur complet à ce stade.

Allez-vous mettre cela en œuvre dans les 10 prochaines années ?

FWIW, j'y reviendrai ce week-end.


@magicgoose a dit :
Allez-vous mettre cela en œuvre dans les 10 prochaines années ?

@pfmoore l'a dit mieux que moi :

Nous sommes conscients que les gens veulent cela, ce qui manque, c'est quelqu'un qui est prêt à développer un correctif qui réponde à toutes les diverses préoccupations et problèmes qui ont déjà été soulevés, et qui apparaîtront inévitablement lors d'un examen des relations publiques.

Donc personnellement, j'apprécierais que les gens s'abstiennent de signaler ce problème à moins qu'ils n'aient un code fonctionnel qui offre au moins un point de départ pour la mise en œuvre - et qu'ils soient prêts à le suivre jusqu'à la mise en œuvre.

avis tout à fait personnel

je pense que par la nature même de pip (qui consiste à installer des packages à partir d'un référentiel qui n'a pas d'assurance qualité globale comme par exemple debian, redhat ou ubuntu)
je pense qu'il est nécessaire et/ou acceptable de s'abstenir complètement d'implémenter et de mettre à jour toutes les fonctionnalités,

puisque nous garantissons toujours un état connu d'un ensemble installable de packages python

@RonnyPfannschmidt IMO, il est parfaitement raisonnable que les utilisateurs de pip interdisent explicitement l'utilisation d'une commande update-all, si cela correspond à leurs exigences / flux de travail. Mais tous les utilisateurs de pip n'ont pas les mêmes exigences strictes que ces personnes. Pour les utilisateurs ayant des besoins plus détendus, une commande update-all est utile, et son absence rend beaucoup plus difficile pour eux de maintenir leurs systèmes "à jour". Je pense donc qu'il est raisonnable que pip fournisse une telle commande. C'est notre travail de fournir les outils dont les gens ont besoin, pas d'appliquer des politiques particulières sur la façon dont les utilisateurs choisissent d'utiliser ces outils.

@pfmoore mon expérience personnelle avec la simple mise à jour de tous les packages dans un environnement est que cela casse les choses très régulièrement ^^

les utilisateurs qui ont besoin d'une mise à jour détendue sonnent comme des utilisateurs finaux normaux (qui devraient simplement utiliser une distribution Linux normale par exemple)

Que la mise à niveau de tout soit problématique ou non dépend beaucoup du nombre de dépendances que vous avez et de leur degré de discipline en ce qui concerne la maintenance de leur API. Il peut également être utilisé avec un référentiel privé organisé pour contrôler les mises à niveau qui se produisent réellement, plutôt que d'avoir à configurer soigneusement les commandes de mise à niveau que vous exécutez dans chaque environnement virtuel.

@RonnyPfannschmidt Les utilisateurs de Windows sont toujours plus nombreux que les utilisateurs de Linux ~ 18 à 1, et ils n'ont rien de comparable à une communauté de gestion de packages de distribution sur laquelle se rabattre à ce stade (alors que la technologie de base est là dans les versions récentes, les communautés d'emballage et de curation ne le sont pas). Cela signifie qu'ils dépendent beaucoup plus d'outils de niveau utilisateur tels que pip et conda pour prendre le relais.

Nous sommes conscients que les gens veulent cela, ce qui manque, c'est quelqu'un qui est prêt à développer un correctif qui réponde à toutes les diverses préoccupations et problèmes qui ont déjà été soulevés, et qui apparaîtront inévitablement lors d'un examen des relations publiques.

@pfmoore savez -vous que de tels commentaires peuvent

Résumé approximatif d'une partie seulement (PR gh-3194) :

  1. Il existe une décision documentée selon laquelle une commande upgrade est la bienvenue (sur la liste de diffusion pip ainsi que sur la documentation et GitHub).
  2. Ensuite, un appel est lancé par un développeur de premier plan ( @njsmith dans ce cas) indiquant que la mise en œuvre de cette fonctionnalité serait très précieuse.
  3. Un nouveau contributeur apparaît, met tout en œuvre, répond rapidement à tous les commentaires. PR prêt à fusionner.
  4. Le contributeur principal change d'avis sur le fait de vouloir upgrade .
  5. De très longues discussions s'ensuivent, sans conclusion.
  6. Le contributeur abandonne et disparaît (la plupart des gens le feraient, de telles choses sont frustrantes).

Et c'était avant même l'arrivée de @pradyunsg , qui fait preuve d'une persévérance remarquable.

Dans un projet qui fonctionne bien, les principaux développeurs qui se soucient vraiment du problème organiseraient une rencontre rapide et prendraient une sorte de décision. Ou déléguez une ou deux personnes pour y travailler suffisamment pour obtenir cette conclusion. Ou à tout le moins, excusez-vous et remerciez l'auteur des relations publiques, au lieu de lui reprocher de "ne pas donner suite".

Je sais que vous avez les meilleures intentions, mais soyez un peu plus prudent avec ce genre de commentaire.

Je pense qu'il est parfaitement raisonnable que les exigences et les opinions changent à travers la discussion, en particulier pour un problème épineux comme celui-ci où il n'y a pas de bonne réponse. Une partie de l'obtention d'un correctif dans n'importe quelle base de code consiste à suivre les modifications qui sont hachées dans le cadre de la révision et de la discussion autour de tout changement. Certains changements sont assez minimes et en ont moins, d'autres en ont plus. Il n'y a rien de mal à ce qu'une personne décide qu'elle ne veut pas gérer cela et abandonne (chaque barre à l'ajout d'un changement entraînera une certaine perte, y compris les tests, la documentation, etc.).

Ce changement particulier est particulièrement désagréable car il modifie le comportement par défaut de l'utilisation principale de pip. C'est difficile et effrayant et ce serait rendre un mauvais service à nos utilisateurs si nous nous précipitions et ne faisions pas tout le hachage avant de nous engager dans un sens ou dans l'autre. Cette commande est utilisée 10s à 100s des millions de fois par mois. Ce n'est pas un petit changement facile et ce ne seront pas les personnes qui signalent ce problème qui devront faire face à la réaction de colère qui découle de tout changement.

La personne qui a mis en œuvre le PR auparavant, leur temps est apprécié, mais c'est un fait qu'ils n'ont pas suivi jusqu'à la fin. Comme les développeurs principaux ici _notre_ temps est limité, nous sommes soit des bénévoles soit répartis entre de nombreux projets et nous flottons dans et hors de la participation. Il y a une tonne de problèmes différents qui nécessitent tous une attention et ce n'est que l'un d'entre eux. Paul a simplement déclaré que le ping de ce problème n'est pas utile (ce qui n'est pas le cas) et que si quelqu'un le veut, il devra soit attendre que quelqu'un (y compris l'un des développeurs principaux) décide de faire l'effort considérable pour modifier le comportement par défaut de millions de personnes ou le faire eux-mêmes.

Nous sommes conscients que les gens veulent cela, ce qui manque, c'est quelqu'un qui est prêt à développer un correctif qui réponde à toutes les diverses préoccupations et problèmes qui ont déjà été soulevés, et qui apparaîtront inévitablement lors d'un examen des relations publiques.

@pfmoore savez -vous que de tels commentaires peuvent

@rgommers Sérieusement ? Ce commentaire datait d' il y a des mois et a été cité hors contexte ici (mais franchement, je n'ai aucun problème à ce que

Si j'étais aussi "hors de la base", alors vous auriez pu le dire en mai au moment où je l'ai dit, plutôt que de le reprendre maintenant, hors de son contexte.

Si j'ai offensé quelqu'un, je m'en excuse, ce n'était pas mon intention. Honnêtement, je suis aussi frustré que n'importe qui d'autre que ce problème s'avère si difficile à atteindre un design qui soit acceptable pour tout le monde. Dans mes commentaires, j'essaie de trouver un équilibre - d'une part, j'apprécie vraiment les contributions des gens, mais d'autre part, je pense qu'il est important de faire comprendre aux gens que sur une question comme celle-ci, le le codage est franchement le moindre des travaux nécessaires. Très souvent, les contributeurs n'apprécient pas ce fait, et c'est là que nous obtenons des PR incomplets, où les gens sont frustrés par le travail nécessaire pour persuader les gens que leur conception est correcte, et/ou pour retravailler le changement, peut-être d'une manière qu'ils ne font pas. J'aime vraiment prendre en compte les points de vue des autres (souvent contradictoires et incohérents !). Je préférerais qu'ils entrent dans le processus avec une compréhension de ce qui est impliqué, plutôt que d'arriver avec des attentes irréalistes et, par conséquent, d'avoir une mauvaise expérience.

Toutes les personnes impliquées dans les discussions sur cette question ont consacré _beaucoup_ de temps à débattre des avantages et des inconvénients des différentes approches. Je ne pense pas qu'il y ait quelqu'un qui soit content du temps que ça prend. Personnellement, l'absence d'une commande upgrade-all (juste une partie du changement, et probablement pas celle qui sera implémentée en premier) me frappe régulièrement. Nous obtenons occasionnellement (honnêtement, c'est bien plus qu'"occasionnellement") des personnes (généralement des personnes qui n'ont pas réellement contribué à la discussion ou au code) à commenter "c'est important, pourquoi ne l'avez-vous pas encore mis en œuvre ?" Franchement, il est difficile de rester calme et de ne pas s'en prendre à de telles personnes.

Dans un projet qui fonctionne bien, les principaux développeurs qui se soucient vraiment du problème

Vous vous rendez compte que ce commentaire peut être interprété comme disant que les développeurs de pip ne se soucient pas de résoudre ce problème (et par implication de pip) ? Nous risquons tous de formuler des choses d'une manière qui peut offenser les gens. Je suis sûr que vous ne vouliez pas dire cela comme une critique des développeurs pip, veuillez supposer que je n'essaie pas non plus d'offenser qui que ce soit.

organiserait une rencontre rapide et prendrait une sorte de décision.

Je serais surpris si quelque chose comme ça marcherait ici, mais je suis prêt à l'essayer. Je ne sais pas qui serait impliqué ou comment nous le gérerions, mais bien sûr, si cela aide et que quelqu'un veut essayer cette approche. Je dirais que, comme ce changement a un si grand potentiel d'affecter les utilisateurs de pip, toute décision prise sur une chaîne privée comme celle-ci devrait probablement être rédigée en tant que proposition et publiée pour commentaires généraux - et je soupçonne que cela déclencherait simplement encore une autre série des mêmes débats que nous avons eus.

Ou déléguez une ou deux personnes pour y travailler suffisamment pour obtenir cette conclusion.

Donc vous dites qu'une décision aussi importante devrait être prise unilatéralement par quelques personnes ? C'est peut-être la seule façon d'obtenir une résolution, mais ce n'est pas vraiment la façon dont les décisions sont prises sur pip (contrairement à Python, nous n'avons pas de BDFL avec un pouvoir décisionnel exécutif). Vous pouvez prétendre que cela fait de nous un "projet qui fonctionne bien" si vous voulez, ce n'est pas mon point de vue, mais nous pouvons être en désaccord là-dessus si vous le souhaitez.

Ou à tout le moins s'excuser et dire merci à l'auteur des relations publiques,

Je ne sais pas pourquoi nous devrions nous excuser, mais si cela peut aider, je m'excuserai avec plaisir - pour le fait que personne ne lui a clairement fait comprendre à quel point ce serait une tâche difficile que de mener à bien cette proposition, ou l'a aidé à gérer le débat et à guider les participants vers un consensus. Mais pour être juste, je ne pense pas que quiconque _autre_ impliqué savait à l'époque que ce serait le cas, donc je pense que c'est principalement avec le recul qui parle ici.

Il a certainement mes remerciements. C'est assez facile de dire "ça va sans dire", mais ça ne devrait pas - les projets open source ne remercient pas assez les contributeurs, et c'est un problème. Pendant que j'y suis, je voudrais remercier _tout le monde_ qui a contribué à ce débat - et je suis tout à fait sérieux ici - car je sais par expérience à quel point il peut être épuisant. Mais surtout à @pradyunsg pour être la victime actuelle de toutes les discussions et changements de direction sans fin. Merci de ne pas abandonner ! (Encore!!)

au lieu de lui reprocher de "ne pas avoir suivi".

Eh bien, je ne pense pas qu'il y ait de blâme (même s'il est difficile de savoir s'il s'est senti blâmé, car il n'est plus là). Mais il est vrai que son RP d'origine n'a pas été mené à terme. C'est juste un fait, cependant. J'espère que personne ne suggère que les contributeurs ont le droit de faire accepter leurs PR _simplement parce qu'ils les ont soumis_. Tous les PR ne sont pas acceptables lorsqu'ils sont soumis pour la première fois, ils doivent être révisés et mis à jour, et parfois même après tout le travail, ils ne sont _toujours_ pas acceptables. Désolé, mais c'est la vie.

[Si je semble dur dans la déclaration ci-dessus, je m'excuse (encore une fois !). Mais une grande partie de mon temps libre est consacrée à la lecture et au traitement des plaintes que moi (ou des projets auxquels je suis impliqué) n'ai pas fait assez. Et c'est un cercle vicieux - je perds la motivation pour travailler sur l'open source pendant mon temps libre à cause de la lancinante, ce qui signifie bien sûr encore moins de travail. Alors que j'essaie de rester poli, parfois ce n'est pas facile]

Je n'ai pas l'intention de dire quoi que ce soit de plus sur cette méta-discussion sur la façon dont le PR est géré. J'ai passé une heure ce soir à travailler sur cette réponse, pour essayer d'éviter de dire quoi que ce soit qui puisse offenser quelqu'un (et je parie que j'ai échoué :-(). Et j'aurais pu beaucoup mieux passer ce temps - avec ma famille, me détendre, ou faire quelque chose de plus productif.

Alors, puis-je suggérer que nous revenions à essayer d'aider @pradyunsg à trouver un PR dont nous puissions tous être satisfaits, et de laisser de côté les méta-discussions infructueuses ?

Alors, puis-je suggérer que nous revenions à essayer d'aider @pradyunsg à trouver un PR dont nous puissions tous être satisfaits, et de laisser de côté les méta-discussions infructueuses ?

Oui s'il vous plaît. :innocent:

Oh j'ai oublié.

@rgommers a dit :
Et c'était avant même l'arrivée de @pradyunsg , qui fait preuve d'une persévérance remarquable.

Je vais prendre ça comme un complément... Merci.

@pfmoore a dit :
surtout à @pradyunsg pour être la victime actuelle de toutes les discussions et changements de direction sans fin. Merci de ne pas abandonner !

Je t'en prie.

(Encore!!)

J'espère vraiment qu'il n'en arrivera pas à cet état. Ce sera un très mauvais état des choses si c'est le cas, OMI. (Je suis arrogant comme ça)

J'ai écrit ce qui suit pendant que je révisais l'historique et j'ai pensé que je pourrais aussi bien le mettre ici, pour référence future et laisser les autres me corriger juste au cas où.

  • J'ai décidé de travailler là-dessus après avoir réalisé à quel point le grand rapport non technique:technique serait (c'est beaucoup plus grand que je ne le pensais vraiment) et en réalisant qu'il y avait déjà eu une tentative infructueuse à ce sujet.
  • J'ai fait un compte rendu sur l'état des choses, parce que je m'ennuyais et j'avais besoin de savoir ce qui s'était passé de toute façon.

    • J'ai probablement passé plus de temps (et d'espace ici ?) dessus que nécessaire, mais au moins j'ai eu un bon aperçu du problème pour moi-même (et pour tout le monde ?).

  • J'étais surexcité après l'avoir écrit. :smiley: Je l'ai montré au monde !
  • Lancement d'une (longue !!!) discussion sur l'implémentation d'une commande de mise à jour.

    • Quelques idées dérivées utiles sont ressorties des discussions. De nouveaux problèmes ont été créés pour le même.

  • La discussion mène à l'idée de changer le comportement d'installation pour installer, ce qui ferait par défaut des mises à niveau peu enthousiastes et supprimerait une partie des fonctionnalités fournies par l'option --target - 3 choses.

    • C'est là que nous avons fait une erreur - regrouper les 3 changements (assez) indépendants et qui seraient mis en œuvre comme un seul, car personne n'a réalisé cette partie.

  • J'ai implémenté la même chose. Étant donné que les 3 changements ont été regroupés, ils sont tous restés bloqués alors qu'il n'y avait pas de consensus sur la modification du comportement d'installation pour upstall, le changement potentiellement controversé.
  • L'absence de consensus a déclenché une longue discussion qui est arrivée au point où les gens se sont retirés de la discussion et j'imagine qu'ils ont presque poussé à l'épuisement professionnel.

    • Certaines des hypothèses précédentes ont été brisées et il a été décidé que nous ferions d'abord un changement de perturbation minimal.

  • J'ai manqué de temps libre pour travailler dessus, j'ai donc créé quelques nouveaux problèmes afin que quelqu'un d'autre puisse y travailler de manière indépendante et idéalement, ne pas commettre la même erreur que nous.
  • Au point mort.
  • Je suis de retour! J'essaierai de passer par défaut aux mises à niveau non désireuses d'ici le 25 septembre.

Oui, concentrons-nous simplement sur la réparation de pip install --upgrade et laissons tout le reste de côté pour le moment. C'est une exigence pour tout autre travail de toute façon.

@pfmoore @dstufft merci pour les réponses réfléchies. Je n'avais pas l'intention d'offenser qui que ce soit, alors je m'excuse si c'est ainsi.

Je ne répondrai pas à tout, car personne ne cherche ici une longue discussion.

tu aurais pu le dire en mai à l'époque où je l'ai dit,

J'étais alors loin de Github pendant 2 mois, mais cela m'a dérangé quand j'ai vu ce commentaire la première fois.

Donc vous dites qu'une décision aussi importante devrait être prise unilatéralement par quelques personnes ?

Toutes les options sur la table sont bien meilleures que le statu quo. Et après 5,5 ans et plusieurs centaines de commentaires répartis sur plusieurs problèmes/RP ici et sur la liste de diffusion, je ne suis pas convaincu que d'autres commentaires vont le résoudre. J'espère que cela sera résolu, mais si cela se bloque à nouveau, alors définitivement oui - nommez une ou deux personnes et faites simplement un choix.

Je ne sais pas pourquoi nous devrions nous excuser, mais si cela peut aider, je m'excuserai avec plaisir - pour le fait que personne ne lui a clairement fait comprendre à quel point ce serait une tâche difficile que de mener à bien cette proposition, ou l'a aidé à gérer le débat et à guider les participants vers un consensus.

Je voulais dire ce dernier. Parfois je change d'avis sur une décision pour un de mes projets, ça arrive. Ensuite, je me sens responsable d'indiquer clairement la nouvelle direction. Et excusez-moi si je n'ai pas le temps de gérer les conséquences de ce changement (cela ne prend que 30 secondes....).

Mais il est vrai que son RP d'origine n'a pas été mené à terme. C'est juste un fait, cependant.

C'est un point de vue, pas un fait. À mon avis, le PR était terminé - il ne restait plus qu'à appuyer sur le bouton vert ou à le rejeter. Il a fait tout ce que j'attendais d'un contributeur.

J'ai réalisé après votre réponse que les attentes des développeurs pip vis-à-vis des contributeurs et des développeurs principaux sont très différentes de pratiquement tous les autres projets que je connais. Je m'attends à ce que les développeurs principaux guident les nouveaux contributeurs, les encouragent, leur donnent des commentaires si nécessaire et les aident à résoudre les problèmes litigieux (pour lesquels la plupart des contributeurs n'ont ni les compétences ni l'intérêt, et ceux qui finissent souvent par devenir des développeurs principaux) si avait besoin. Vous dites aux nouveaux contributeurs : _"vous devez nous gérer. Nous pouvons changer d'avis, être en désaccord les uns avec les autres ou perdre tout intérêt - c'est votre travail de gérer cela"_. C'est peut-être la nature de ce projet et il doit en être ainsi, je ne sais pas.

Tant que j'y suis, je tiens à remercier tous ceux qui ont contribué à ce débat

D'accord. Merci à tous ceux qui ont contribué.

  • et je suis tout à fait sérieux ici - car je sais par expérience à quel point cela peut être épuisant.

C'est drainant. Personnellement, je reste ici et sur distutils-sig car c'est important pour l'écosystème Python et les utilisateurs de mes packages, mais les deux endroits ne me donnent pas exactement une énergie positive.

Juste au cas où ça passerait inaperçu - #3972 :sourire:

Vous dites aux nouveaux contributeurs : "vous devez nous gérer. Nous pouvons changer d'avis, être en désaccord les uns avec les autres ou perdre tout intérêt - c'est votre travail de gérer cela". C'est peut-être la nature de ce projet et il doit en être ainsi, je ne sais pas.

J'ai dit que je ne continuerais pas cela, mais ce point a frappé à la maison. Ce n'est pas ce que je ressens à propos de notre approche, mais maintenant que vous l'exprimez ainsi, je vois que cela peut être perçu de cette façon. Pour être honnête, "nous pouvons changer d'avis, être en désaccord les uns avec les autres ou perdre tout intérêt" est vrai - après tout, nous ne sommes tous que des personnes avec d'autres engagements - mais je ne considère pas cela comme quelque chose qu'un nouveau contributeur doit "faire en sorte". Au contraire, il s'agit simplement de traiter avec les gens, mais si en faire trop revient à rejeter le problème sur les nouveaux contributeurs, c'est faux.

Merci de l'avoir signalé - je vais essayer de le garder à l'esprit et d'éviter de donner cette impression à l'avenir.

Je pense que le problème se résume en grande partie au fait que nous manquons énormément d'effectifs, ce qui finit par rendre difficile le suivi et le suivi de tout. Il y a plus de contributeurs potentiels que nous, il est donc facile de se sentir dépassé lorsqu'il y a plusieurs personnes qui essaient toutes d'apporter des changements à la fois. Les changements plus importants, ou les changements pour lesquels il n'y a pas de consensus clair, ont tendance à être les plus difficiles à gérer, ce sont donc ceux qui ont tendance à souffrir le plus :(

Le triste état des choses est que même si je pense que nous aimerions tous être ici pour aider à guider tous les contributeurs tout au long du processus, nous n'avons tout simplement pas la main-d'œuvre. Cela a également tendance à avoir un cycle visqueux, car nous n'avons pas la main-d'œuvre pour le faire, nous ne trouvons pas facilement de nouvelles personnes qui semblent avoir vraiment commencé à comprendre la mentalité derrière le fonctionnement de Pip et qui ont appris assez (parce que nous ne sommes pas là pour leur enseigner) pour leur donner des droits de commit sur pip. Cela signifie que nous sommes constamment en sous-effectif et que nous luttons simplement pour garder la tête hors de l'eau (du moins, c'est ce que je ressens. Des semaines constantes de 70 à 90 heures sont vraiment difficiles pour une personne :/).

@pradyunsg Reviewing #3972 est sur ma liste TODO, je ne l'ai tout simplement pas encore touché.

@pradyunsg Reviewing #3972 est sur ma liste TODO, je ne l'ai tout simplement pas encore touché.

Merci!

Cela signifie que nous sommes constamment en sous-effectif et que nous luttons simplement pour garder la tête hors de l'eau (du moins, c'est ce que je ressens. Des semaines constantes de 70 à 90 heures sont vraiment difficiles pour une personne :/).

C'est dur. Numpy et Scipy étaient dans cette situation quand j'ai commencé à travailler dessus. Pas drôle. J'apprécie tout ce que vous faites.

Ce problème est maintenant très long et très ancien, beaucoup de choses ont été discutées, trop de choses se sont produites et ce problème a presque atteint un faible signal/bruit. Il est difficile de voir ce qui s'est passé.

FWIW, la raison pour laquelle upgrade était sur les cartes était due au fait que install --upgrade a un défaut cassé. Étant donné que nous sommes maintenant à un pas de plus de la résolution de ce problème, je suppose qu'il est préférable que nous ayons un nouveau problème pour cela.

Je suggère que ce problème soit fermé en raison de ce qui précède et que de nouveaux problèmes soient créés pour tout ce qui est considéré ici comme non résolu. Je vois 2 choses :

  • Décalez la stratégie de mise à niveau par défaut sur only-if-needed .
  • Ajoutez la fonctionnalité "mettre à niveau le monde" qui dépend de #988.

Le 15/09/16, Nick Coghlan [email protected] a écrit :

@RonnyPfannschmidt Les utilisateurs de Windows sont toujours plus nombreux que les utilisateurs de Linux ~ 18 à 1, et
ils n'ont rien de comparable à une communauté de gestion de paquets de distribution
se rabattre à ce stade (alors que la technologie de base est là depuis peu
versions, les communautés de packaging et de curation ne le sont pas). Cela signifie qu'ils sont
beaucoup plus dépendant d'outils de niveau utilisateur tels que pip et conda pour récupérer le
mou.

N'est-ce pas alors
mise à jour conda --all
assez bien?

@Liso77
Eh bien, non. Ce n'est pas le cas.

Conda et pip sont des outils avec des objectifs différents. C'est une excellente lecture sur ce sujet. Le 3ème point est le plus pertinent.


Si la discussion sur la mise à niveau de tous fait surface à nouveau (espérons-le dans un nouveau numéro), mon vote est pour l'épeler comme suit :

pip install --upgrade :all:

pip install --upgrade :all: est extrêmement étrange. Tenons-nous en à la sémantique POSIX, ce que tout le monde fait de nos jours : pip install --upgrade --all

Qu'en est-il seulement de pip install --upgrade sans aucun nom ni spécificateur de package ? Trop facile à exécuter accidentellement ?

pip-tools fait comme ça pour pip-compile -P .

Peut-être qu'on devrait ranger les vélos une fois qu'on a une sorte de travail
la mise en oeuvre... :)

Le dimanche 12 février 2017, 20:55 FichteFoll [email protected] a écrit :

Qu'en est-il de pip install --upgrade sans aucun nom de paquet ou
spécificateurs ? Trop facile à exécuter accidentellement ?

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/pypa/pip/issues/59#issuecomment-279225595 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/ADH7SfnSBflH8rK3nFLw1hvYBaovjbcGks5rbyRUgaJpZM4AJ4Py
.

Que diriez-vous d'une version de pip list --outdated qui produit sa liste dans un format qui peut être directement (c'est-à-dire, sans sed , cut , etc.) ingérée par pip install --upgrade (par exemple, pip list --outdated --format install | xargs pip install --upgrade ou quelque chose de similaire avec des backticks) ?

quelle que soit la syntaxe qui sera utilisée, la chose la plus importante est d'introduire cette commande, c'est incroyable qu'elle manque encore

en attendant je vous propose d'essayer
https://github.com/jgonggrijp/pip-review
avec pip-review --local --interactive vous demander package par package si vous souhaitez mettre à jour, pas très bien mais mieux que rien

@ SMH17 Il est tout à fait crédible qu'il manque toujours, car il n'y a exactement aucun fournisseur Python commercial fournissant officiellement du temps de développement financé pour travailler sur les améliorations de la convivialité des emballages Python au nom de leurs clients.

Donc , si vous souhaitez voir la situation à améliorer, il est probable que vous pouvez faire personnellement la chose la plus utile est d'encourager soit votre fournisseur de support de Python à investir du temps des développeurs à améliorer les outils que vous utilisez, ou si vous ne disposez pas

Comme élément de contexte supplémentaire concernant le manque d'urgence autour de cette question, il convient de garder à l'esprit que les recommandations générales sont de

  • gardez vos définitions d'environnement de travail sous contrôle de source pour améliorer la reproductibilité sur d'autres systèmes (en utilisant quelque chose comme https://github.com/jazzband/pip-tools ou https://github.com/kennethreitz/pipenv pour maintenir ces définitions à jour )
  • viser à mettre à niveau régulièrement vers de nouvelles versions de dépendances afin de minimiser les fenêtres d'exposition à des vulnérabilités de sécurité inconnues ou non divulguées

Cela ne veut pas dire que les commandes proposées ici ne sont pas utiles, elles sont juste nettement moins utiles si l'environnement de travail actuel est déjà maintenu via pip-compile + pip-sync , ou pipenv lock + pipenv install .

Il serait utile de mettre à jour la description d'origine car je suppose que des modifications ont été apportées à pip install depuis la mise à jour effectuée par @qwcode.

Salut à tous.

J'ai cassé certaines de mes dépendances de package python à cause de la commande suivante :

pip install --upgrade packageName a mis à jour les packages de manière récursive.

Pourquoi ne pas changer le comportement par défaut de l'option --upgrade , c'est-à-dire désinstaller et réinstaller UNIQUEMENT le package donné à partir de la ligne de commande ?

Que dis-tu de ça ?

@sebma Je pense que le comportement par défaut ne doit pas être modifié. Vous pourriez peut-être essayer d'utiliser le drapeau -no-dependencies la prochaine fois. ça devrait marcher :+1:

@sebma , @aaossa , je vous ferai savoir tous les deux qu'il a déjà été à peu près décidé que la stratégie de mise à niveau par défaut changera à l'avenir (réf : https://github.com/pypa/pip/issues/3871# questioncommentaire-247789343). La fonctionnalité nécessaire (c'est-à-dire l'argument --upgrade-strategy ) a été ajoutée dans https://github.com/pypa/pip/pull/3972.

Comme @pradyunsg l'a mentionné plus tôt , ce problème est en quelque sorte un reliquat . La première partie est en quelque sorte gérée maintenant (voir mon premier paragraphe) et la deuxième partie est la seule raison pour laquelle ce paquet est toujours ouvert, semble-t-il. Je ne sais pas si un problème distinct de « mise à niveau complète » a été créé depuis.

J'ai publié un joli fichier de mise à niveau interactif pour les exigences : https://github.com/simion/pip-upgrader

Déplacez la stratégie de mise à niveau par défaut sur uniquement si nécessaire.

4500 l'ont fait.

Ajoutez la fonctionnalité "mettre à niveau le monde" qui dépend de #988.

4551 pour en discuter.


Aborder les points soulevés dans le top-post actuel :

pip upgrade serait comme pip install --upgrade sauf qu'il serait non récursif par défaut (et offrirait une option --recursive). Son comportement par défaut récursif actuel a causé du chagrin à beaucoup (#304). Quant à savoir comment faire des mises à niveau non récursives maintenant, voir ici.

Il a été décidé de ne pas ajouter de commande de mise à niveau ou de créer des packages de mise à niveau de pip install déjà installés. pip a maintenant des mises à niveau non récursives par défaut, avec le comportement récursif disponible derrière --upgrade-strategy eager .

pip upgrade-all mettra à niveau tous les packages installés.

4551 existe et ce serait bien d'avoir une nouvelle discussion à ce sujet ; quand #988 est fait.


@dstufft @xavfernandez @pfmoore L' un d'entre vous pense-t-il que ce problème devrait être clos ?

Edit (1805-2017): Ponctuation + texte mineur ajouté

Cela semble raisonnable.

Bonjour à tous,
J'ai fait un script/essentiel simple qui fait le travail.

https://gist.github.com/serafeimgr/b4ca5d0de63950cc5349d4802d22f3f0

Pourquoi ne pas simplement faire ça ?

pip install --upgrade $(pip list --outdated | awk '{print $1}' | tr '\n' ' ')

Parce que ce n'est pas si facile en réalité car vous pouvez installer des versions qui ne satisfont pas certaines des dépendances de vos autres packages.

Sur la base et grâce à @serafeimgr est essentiel , j'ai écrit un outil de ligne de commande peut-utile, pip_upgrade_outdated ; source sur github . Commentaires bienvenus.

(Voir aussi ce numéro : Oui, l'exécution parallèle est particulièrement dangereuse, et, oui, cela peut casser des choses. Néanmoins, beaucoup de gens exécutent quelque chose comme ça à la main tout le temps, donc cela pourrait le trouver utile.)

Merci d'avoir pris le temps de créer une solution complète.
Même si ma recommandation serait de trouver un moyen de pousser cette fonctionnalité à pip.

Je pense que pipenv & pipfile va remplacer pip/requirements.txt de toute façon.
Peut-être que @kennethreitz en sait plus sur la feuille de route et la fonctionnalité --upgrade all.

@qoheniac | tr ... est redondant.

Ce fil a été automatiquement verrouillé car il n'y a eu aucune activité récente après sa fermeture. Veuillez ouvrir un nouveau problème pour les bogues liés.

Cette page vous a été utile?
0 / 5 - 0 notes