Pip: Par défaut à --user

Créé le 21 mars 2014  ·  170Commentaires  ·  Source: pypa/pip

Lorsque pip est installé sur un système doté d'une installation OS Python, il existe actuellement un problème où pip install foo génère une erreur car il ne dispose pas des autorisations de fichier. Cela amène les gens à exécuter à la place sudo pip install foo qui s'installe globalement sur le système Python. Cela crée un problème où les gens utilisent pip pour gérer les packages au niveau du système alors qu'ils devraient probablement utiliser le gestionnaire de packages système.

Donc, mon intention est que pip soit par défaut --user, mais il y a quelques points de blocage avec ceci :

  • Comment cela interagit-il avec Windows ? Cela a-t-il un sens là-bas ?
  • Comment cela interagit-il avec les Pythons altinstallés ? Spécialement ceux qui sont installés avec des outils comme https://github.com/yyuu/pyenv
  • Que faisons-nous lorsque les gens invoquent pip en tant que root ? L'installation dans /root/.local/ ne semble pas très utile.
  • Qu'est-ce que cela signifie pour get-pip et les instructions d'installation de pypa ?
  • ~/.local/bin n'est pas sur le $PATH de beaucoup de gens, y a-t-il quelque chose qui puisse être fait à ce sujet ?
  • Les installations --user n'ont pas la priorité sur les packages globaux easy_install , ce qui peut être assez inattendu.

Il y a un certain nombre de problèmes qui sont pertinents ici : #624 #1443 #1153 #1500 #1051

/cc @ncoghlan

user scheme auto-locked enhancement

Commentaire le plus utile

J'ai rêvé la nuit que l'option --user devienne la valeur par défaut (je ne plaisante pas), y a-t-il une chance que mes rêves se réalisent bientôt ?

Tous les 170 commentaires

Qu'est-ce que cela signifie pour les instructions d'installation de pypa ?

actuellement, la mention de l'accès root ou administrateur est dans une note de bas de page, de sorte que les instructions resteraient fondamentalement les mêmes (en supposant que get-pip automatiquement défini par défaut sur --user également). le changement serait d'expliquer qu'ils se retrouveront avec des installations qui ne s'appliquent qu'à leur utilisateur actuel.

quel que soit le changement --user , les instructions actuelles doivent expliquer que certaines distributions comme debian désactivent l'assurepip, elles ne devraient donc pas le chercher comme moyen d'obtenir le pip.

À long terme, je suis presque sûr qu'ils vont le garder activé, ils sont juste en train de trouver comment le faire.

bien que ce problème soit décrit comme portant sur l'endroit où pip devrait gérer les packages par défaut, le plus important (du moins pour moi) est qu'il s'agit indirectement de l'endroit où get-pip placera pip par défaut.

Comment cela interagit-il avec les Pythons altinstallés ?
Spécialement ceux qui sont installés avec des outils comme https://github.com/yyuu/pyenv

le schéma utilisateur est .local/lib/pythonX.Y/site-packages , donc si vous gérez plusieurs pythons avec la même version majeure/mineure, vous pourriez vous retrouver avec un gâchis, je suppose.

pour des outils comme celui-là, qui gèrent de vrais pythons, épingler pip en mode global aurait du sens pour ceux-là.

Un problème pertinent sur le traqueur de bogues redhat/fedora https://bugzilla.redhat.com/show_bug.cgi?id=662034#c10

Il semble que pour Fedora/RedHat, PATH=$PATH:$HOME/.local/bin:$HOME/bin soit déjà dans leur /etc/skel/.bash_profile . Cela ferait en sorte que les éléments installés avec --user s'affichent toujours par défaut, du moins pour les utilisateurs de bash (shell par défaut). Peut-être que d'autres distributions l'ont déjà ?

Il n'y a rien de particulièrement différent à propos de Windows que je connaisse. Mais nous venons tout juste d'avoir le répertoire Python standard sur le PATH des gens, je ne m'attends pas à ce que l'obtention d'un répertoire de scripts par utilisateur soit particulièrement facile - et il peut également y avoir des difficultés techniques, je ne suis pas sûr mettre une variable d'environnement au niveau de l'utilisateur comme %LOCALAPPDATA% dans le système %PATH% fonctionne même :-(

Je suis contre la précipitation. Je préférerais attendre que nous ayons plus d'expérience avec les installations d'utilisateurs et que nous ayons réussi à résoudre les problèmes en premier. Je sais que c'est un problème de poules et d'œufs, mais je ne vois pas se précipiter dans un changement comme une aide.

De plus, avec mon chapeau Windows, je dois dire que rendre plus difficile pour les utilisateurs d'Unix qui n'ont pas encore compris que l'utilisation négligente de sudo est mauvaise pour faire des choses stupides, n'est pas vraiment une bonne justification. .

Je suppose que cela ne s'appliquerait que lors de l'exécution de pip à partir d'un système Python.

Eh bien, la différence avec Windows est qu'il n'y a pas de système Python fourni comme il y en a sur * nix qui est également fourni avec les packages Python fournis par le système :)

Je n'ai pas particulièrement envie de me précipiter non plus. Je voulais juste lancer la discussion.

Cela n'affecte pas vraiment les personnes qui tapent sudo pip install car je pense que l'installation de quelque chose en tant que root devrait toujours aller aux packages du site système par défaut. Ce serait pour guider les gens vers l'utilisation --user lorsqu'ils s'exécutent en tant qu'utilisateur non privilégié. En ce moment, ce que vous obtenez, c'est que pip install en tant qu'utilisateur régulier vient de bombarder avec une erreur d'autorisation. Même si nous améliorons ce message pour bombarder et suggérons --user , ce n'est toujours pas le meilleur UX.

En parlant à l'une des personnes de Fedora, je pense que la façon dont il peut faire cela est de mettre en œuvre une vérification des autorisations. Si j'ai l'autorisation d'écrire dans le répertoire site-packages, je suis un utilisateur privilégié et pip s'installe sur le Python global. Si ce n'est pas le cas, je suis un utilisateur non privilégié et il s'installe sur --user .

En ce qui concerne Windows, nous esquivons généralement le problème car nous installons Python dans un répertoire non privilégié par défaut, donc pip ne déclenche pas l'UAC lors de l'installation globale. Si quelqu'un change cela pour l'installer dans Program Files à la place, alors l'UAC se déclenchera lorsqu'il exécutera pip (ce qui est également OK). Je ne sais pas ce qui se passe s'ils sélectionnent une installation par utilisateur dans le programme d'installation.

Comme le note Paul, PATH sur Windows n'inclut pas encore le répertoire _user_ scripts (juste le répertoire global), donc cela vaut vraiment la peine d'être pris en compte.

Je ne vois cependant aucun obstacle majeur du côté de POSIX. Comment cette idée UX sonne-t-elle : pour les installations basées sur la roue, vérifiez les autorisations sur le répertoire cible de l'installation, et si l'utilisateur n'a pas les autorisations d'écriture, affichez une invite lui demandant s'il souhaite effectuer une installation --user à la place ? Un nouveau drapeau "--global" ou "--system" forcerait la réponse "non".

Et puis, à un moment donné dans le futur, nous pourrions ignorer l'invite et simplement supposer --user si les autorisations n'étaient pas correctes pour une installation globale.

Une invite (sauf dans le cas de --no-input) a probablement du sens pour l'étape de transition. Je pense que la vérification des autorisations devrait également faire fonctionner les choses pour Windows car, par défaut, l'emplacement est à un endroit où les gens ont des autorisations et donc la seule fois où ils le feraient, ce serait s'ils utilisaient un administrateur système fourni Python qui l'a fait explicitement ' t leur donner la permission.

Essentiellement, cela rend notre mode d'échec bien meilleur.

ce qui rend la tâche plus difficile pour les utilisateurs d'Unix qui n'ont pas encore travaillé sur cette utilisation imprudente de sudo
c'est mal de faire des bêtises, c'est pas vraiment une bonne justification..

sudo et la sécurité est vraiment un problème secondaire à l'OMI.
il s'agit principalement d'empêcher le conflit entre l'empaquetage du système d'exploitation et pip dans le système python.
Actuellement, les utilisateurs Linux sont souvent placés dans une situation impossible.

  1. Mandat du système d'exploitation : 'Utiliser le gestionnaire de pkg du système d'exploitation ; N'infectez pas votre système avec des packages installés par roque pip (y compris un get-pip 'd pip)'
  2. Réalité : "Les packages du système d'exploitation (y compris pip) sont trop anciens et je ne peux pas passer à la version expérimentale de la distribution, juste pour obtenir des mises à niveau de certains packages. Je deviens un voyou...."

une autre petite étape consiste à documenter (en supposant que nous le testions) que vous pouvez get-pip.py --user , et que le PUG mentionne --user comme possibilité d'installation de virtualenv (et wheel , et twine aussi, si ce n'est pas dans un environnement virtuel)

FWIW, les fournisseurs de distribution considèrent également le statu quo comme un problème et étudient différentes façons d'améliorer les outils permettant d'effectuer des mises à niveau sélectives sans affecter les composants centraux du système d'exploitation. Cela vaut toujours la peine que nous nous attaquions en amont, car ces efforts sont à divers stades de maturité et nous voulons une solution multiplateforme cohérente pour les utilisateurs finaux.

Je n'ai aucun problème à changer les choses pour aider à coopérer avec les distributions sur Unix ; si la valeur par défaut de --user sous Unix et non sous Windows est acceptable, ça me va. Je ne vois tout simplement pas passer d'une mauvaise expérience sous Unix à une mauvaise expérience sous Windows comme un bon compromis. Et je ne suis pas encore convaincu que --user sur Windows est prêt pour les heures de grande écoute.

Notez que le déclenchement de l'UAC lors de l'exécution de pip _est_ mauvais sous Windows, car cela signifie en réalité que pip ne s'exécutera que dans une fenêtre de console élevée. Cela ne signifie pas que les utilisateurs de pip reçoivent une belle invite à laquelle ils peuvent dire "OK", malheureusement, c'est seulement ainsi que fonctionnent les applications GUI ...

@pfmoore Que pensez-vous que l'expérience utilisateur de Windows devrait être lorsque vous pip install quelque chose et que vous n'avez pas les autorisations pour écrire dans le répertoire?

FWIW Je suis tout à fait d'accord pour rendre cela facultatif en fonction de Windows ou non. Je me demande simplement si la vérification "Ai-je les autorisations d'écrire dans le dossier site-packages" n'atteindra-t-elle pas cela de toute façon dans 99% des installations, et si l'installation sur --user serait une meilleure expérience dans le fraction des cas où vous n'avez pas d'autorisations d'écriture sur le répertoire site-packages.

En d'autres termes, si nous vérifions les autorisations, la proposition ne remplace pas l'installation globale par une installation utilisateur, mais remplace une erreur d'autorisation par une installation --user .

la proposition ne remplace pas l'installation globale par une installation utilisateur
il remplace une erreur d'autorisation par une installation --user

ok, mais rappelez-vous que l'idée de vérification des autorisations (#1048) ne sera pas la chose la plus facile

Ce sera assez facile dans le cas de Wheel, et nous pouvons recouvrir le cas à 99,9% de sdists, cela ne devrait être un problème que dans setup.py qui fait des choses vraiment géniales.

Selon vous, quelle devrait être l'expérience utilisateur de Windows lorsque vous installez quelque chose et que vous n'avez pas les autorisations pour écrire dans le répertoire ?

Eh bien, être capable d'écrire dans le répertoire site-packages est si rare sous Windows que je ne suis pas sûr de la pertinence de la question dans la pratique. Mais si cela se produisait, je dirais qu'une erreur disant "les packages du site système ne sont pas accessibles en écriture - vouliez-vous utiliser --user ?" serait l'approche sensée.

En fait, je pense que ce serait mieux sur Unix aussi. Changer le comportement en fonction de l'inscriptibilité est bizarre, et je ne sais pas si l'utilisation --user pour un Python personnellement construit dans un répertoire inscriptible est la bonne approche (mais je n'ai précisément aucune expérience d'une telle configuration, donc Je n'ai rien pour étayer cette opinion).

Suggestion : Commencez par une erreur suggérant --user comme ci-dessus. Une fois que les gens utiliseront --user plus couramment, et que nous aurons plus d'expérience avec cela, envisageons de changer la valeur par défaut.

L'approche suggérée par Paul est à peu près ce que j'avais en tête, mais avec une invite oui/non plutôt que de renflouer avec un message d'erreur. Il y a des avantages et des inconvénients à ces deux approches (principalement liées à la façon dont elles échouent lorsqu'elles sont invoquées à partir d'un autre script).

Serait-il possible d'ajouter à Python quelque chose comme sys.localprefix (je vois python-dev ici) ?
Sys.localprefix serait par défaut sys.prefix. Les distributions pourraient le définir de la même manière qu'ils définissent le préfixe (par exemple, préfixe = '/usr', localprefix='/usr/local'). Pip et easy_install utiliseraient sys.localprefix comme emplacement d'installation s'ils sont utilisés comme sudo, s'ils n'ont pas les droits suffisants, ils se rabattront sur --user.

Nous avons fait quelque chose comme ça avec « gem install » dans Fedora 17 et les développeurs Ruby en étaient généralement très satisfaits, alors j'ai pensé partager :

  • "gem install foo" installe "foo" dans ~/somedir si uid != 0
  • "gem install foo" installe "foo" dans /usr/local/somedir si uid == 0
  • "yum install rubygem-foo" installe "foo" empaqueté RPM dans /usr/somedir

Je pense que choisir le répertoire d'installation en fonction des privilèges de l'utilisateur serait très déroutant pour les gens; "pip install foo" devrait fonctionner de la même manière pour tous les utilisateurs non root. Si vous considérez la majorité des utilisateurs, ils voudront "installer pip" dans leur maison et "installer pip sudo" dans un répertoire à l'échelle du système. Par conséquent, je pense que c'est la meilleure approche pour le faire en fonction de uid comme indiqué ci-dessus - et pour les utilisateurs qui ne sont pas root mais qui souhaitent installer dans un répertoire à l'échelle du système, il y a toujours l'option --target.

@bkabrda c'est un choix facile à faire tant que vous ne vous inquiétez pas d'ajouter des scripts à $PATH. Qu'avez-vous fait là-bas ?

@Ivoz comme l'a noté @dstufft , Fedora a déjà $HOME/.local/bin sur PATH, donc tout a fonctionné dès le départ (en parlant de scripts).

La suggestion de Slavek me semble bonne pour les systèmes POSIX. Cela devrait également bien fonctionner avec les conteneurs, car on peut dire aux choses qui s'exécutent dans un conteneur de penser qu'il s'agit d'uid 0, même s'il s'agit de quelque chose d'autre entièrement extérieur au conteneur.

Pour Windows, je suis moins sûr de la bonne réponse. Nous n'avons pas tout à fait le même problème d'entrer dans une dispute avec le gestionnaire de packages système, bien qu'il existe dans une certaine mesure (installation pip vs installateurs MSI), et avons la complication supplémentaire que même dans Python 3.4, le PATH facultatif de l'installateur les modifications ajoutent uniquement le répertoire global des scripts, pas celui par utilisateur.

Windows a également des bizarreries selon que Python est installé à l'emplacement par défaut (non contrôlé) ou dans Program Files (élévation des privilèges UAC nécessaire pour apporter des modifications).

L'idée "localprefix" suggérée par @rkuska m'a l' air sympa, simple et facile. De plus, j'aime beaucoup l'approche suggérée par @bkabrda , en particulier pour les distributions comme Arch qui font de python 3.x le python par défaut.

Une autre remarque est qu'Arch a désactivé l'assurepip dans la version 3.4.0, tout comme Debian (principalement parce que nous voulons fournir les dernières versions de setuptools et pip, alors que les versions groupées peuvent être obsolètes depuis des lustres), donc ce serait bien d'avoir un conseil pour cela.

@lvoz
Pour Arch, nous n'avons ajouté aucun chemin sous $HOME à PATH, mais je pense toujours que ça va. Nous avons déjà une entrée wiki pour Ruby qui indique à l'utilisateur de l'ajouter.

Ce serait bien si, plutôt que de simplement le désactiver, les développeurs Arch et Debian aidaient Slavek à travailler sur son patch pour qu'assurepip reconstruise une roue à partir des versions système et l'installe dans des environnements virtuels.

Juste pour votre information, nous avons déjà des builds Python 3.4 RPM fonctionnels dans le système de build Copr de Fedora (test, il n'est pas conseillé de les installer si vous ne voulez rien casser). Si vous voulez en savoir plus sur la façon dont nous abordons cela, jetez un œil au code, etc., consultez ma discussion avec Barry Warsaw [2] sur debian-python ML.
(Nos patchs ont encore besoin d'amour avant de les proposer en amont, mais tout fonctionne bien pour nous en aval ATM)

[1] http://copr-fe.cloud.fedoraproject.org/coprs/bkabrda/python-3.4/
[2] https://lists.debian.org/debian-python/2014/03/msg00046.html

Désolé, mais AFAIK Arch n'a jamais pris en charge la roue, et nous ne voulons pas non plus faire en sorte que le gestionnaire de paquets d'invoquer le gestionnaire de paquets (corrigez-moi si je comprends mal cette approche, cependant).

Pour assurerpip, ce serait une bonne idée d'avertir l'utilisateur de ne pas installer pip à l'aide d'assurepip, et c'est le maximum auquel je puisse penser pour l'instant.

NotreAssurepip n'invoquera jamais le gestionnaire de paquets. En bref, l'assurepip de Fedora s'appuiera sur les outils de configuration du système et pip pour être toujours présent (notre package python3 en dépendra, ce qui créera une boucle de dépendance, mais nous pouvons gérer cela) et lorsque l'utilisateur créera un nouveau virtualenv, il reconditionnera outils de configuration du système et pip dans les roues et installez-les dans le nouveau virtualenv.
Nous commençons à être un peu hors sujet, donc je suppose que nous devrions continuer cette discussion ailleurs...

@felixonmars Cela signifie-t-il que sur Arch venv est cassé de la même manière que sur Debian?

OK, merci pour l'explication, je pense avoir saisi l'idée. Je vais voir ce que je peux faire et faire un suivi sur debian-python pour cela.

@dstufft Oui, la version groupée a été installée à la place de la version système.

@bkabrda Donc, cela résout le problème si vous appelez pip avec un système Python, nous devons cas particulier virtualenv/venv dans ce cas (ce qui n'est pas la fin du monde). Mais cela signifie également que nous supposons que tous les Pythons sont des Pythons système, même ceux installés par l'utilisateur dans leur homedir comme avec https://github.com/yyuu/pyenv (c'est ainsi que j'exécute Python en fait). Donc je ne suis pas sûr, c'est pourquoi j'ai pensé à la vérification des autorisations.

idem ce que @dstufft a dit, en utilisant un outil comme pyenv pour jongler avec des pythons non root, il serait assez étrange que root soit la clé pour faire une installation globale (où "global" != "système")

Nous avons fait quelque chose comme ça avec "gem install" dans Fedora 17

vous voulez dire que le rpm de la gemme pour fedora 17 a cela comme un hack de distribution ?, ou la gemme elle-même a cette logique ?

une pensée est que pip devrait fournir un "mode convivial pour le système" qui peut être activé par les distributions qui empaquetent pip, ou lorsque les utilisateurs savent qu'ils installent eux-mêmes pip dans un python géré par le système. sinon, pip fait sa logique globale par défaut normale.

Ah @felixonmars je viens de voir https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/python , si tout ce que vous faites est d'appeler --without-ensurepip c'est bien . Cela laisse le moduleassurepip intact pour le module venv. Les correctifs qu'Ubuntu (Debian?) a actuellement mis en place appellent en fait rm -rf sur le paquetassurepip lui-même, le rendant indisponible pour être appelé dans un venv.

Je pense que Nick a proposé par défaut les installations d'utilisateurs il y a deux ans, ou peut-être quelqu'un d'autre il y a plus longtemps, mais le fil est allé dans de nombreuses directions et n'a pas été fructueux. Le principal obstacle était la rétrocompatibilité IIRC, mais de nos jours, les administrateurs système et les utilisateurs de pip sont peut-être plus habitués à être prudents avec les mises à jour de virtualenv/pip/setuptools, pour le meilleur ou pour le pire. Je ne me souviens pas si cette discussion a eu lieu sur distutils-sig ou pypa-dev.

@dstufft Oh, je vois ... Mais je me sens toujours mal d'avoir une version groupée (peut-être ancienne) installée alors qu'il y a des packages installés au niveau du système :)

@felixonmars eh bien, le problème est que vous ne pouvez pas installer un package système dans un virtualenv afaik :) (Et même si vous le pouviez, il y a différentes préoccupations avec ce que vous voulez dans un package système par rapport à l'intérieur d'un virtualenv)

@dstufft C'est là que la roue arrière de Slavek entre en jeu, mais c'est un peu hors sujet :)

@dstufft Merci !

Je ne sais pas si je devrais continuer la discussion là-bas, car cela ne devrait pas poser de problème puisque nous n'avons pas dégroupé le pip dans Arch, et la reroue devrait générer une roue utilisable :)

@dstufft , vous avez raison de dire que nous aurions probablement besoin de cas spécial virtualenv et peut-être même pyenv, ce qui semble moche. Je dois admettre que je ne suis pas très familier avec pyenv, donc je ne peux penser à aucune solution "appropriée" pour cela pour le moment. Je vais essayer d'y regarder de plus près et de penser à quelque chose.

@qwcode pour "gem install" sur Fedora, c'est un patch en aval. TBH Je n'ai pas touché les Rubygems de Fedora pendant longtemps, mais la dernière fois que j'ai vérifié, c'était uniquement en aval.

J'ai posté un lien vers ce problème vers un bogue connexe dans python [1]. Je voudrais déplacer cette discussion vers le noyau python, pour avoir un emplacement configurable pour les installations locales non seulement pip mais aussi easy_install et python setup.py install , après que pip pourrait utiliser ( par exemple) répertoire sys.localprefix si uid==0 et installez-le dans le répertoire utilisateur si uid!=0 comme @bkabrda l'a mentionné.

Pour le moment, je suis d'accord avec l'installation de pip dans le répertoire utilisateur par défaut.

[1] http://bugs.python.org/issue1298835

Comme Nick l'a souligné, j'ai déplacé la discussion de issue1298835 vers pypa-dev [1].
[1] https://groups.google.com/forum/#!topic/pypa-dev/r6qsAmJl9t0

Par défaut à --user

Bonne idée!

pip install foo générera une erreur car il n'a pas les autorisations de fichier. Cela amène les gens à exécuter à la place sudo pip install foo qui s'installe globalement sur le système Python

C'est pire que ça. De nombreuses personnes (comme les utilisateurs d'un réseau informatique universitaire) n'ont pas de privilèges sudo. Lorsque pip échoue avec une erreur d'autorisation, ils :

  1. Envoyez un e-mail à leur administrateur et demandez-leur d'installer le package. C'est lent et fastidieux pour tout le monde.
  2. Abandonnez-vous et faites sans le paquet.

Ce n'est que s'ils sont particulièrement expérimentés ou bien informés qu'ils essaieront pip install --user .

Si nous finissons par décider contre 'default to --user', nous devrions envisager les alternatives les moins perturbatrices :

  1. Retour à --user (si l'installation échoue en raison d'erreurs de permissions)
  2. (Si l'installation échoue en raison d'erreurs de permissions), encouragez l'utilisateur (en grandes lettres amicales) à essayer --user

En fait, j'utilise --user dans toutes mes installations depuis un moment maintenant, mais généralement les gens ne sont pas au courant de cette option. Je suis d'accord qu'il est ennuyeux de voir l'erreur d'autorisation à chaque fois que vous oubliez l'option. J'ai remarqué que les installations d'utilisateurs ne sont pas compatibles avec conda (conda/conda#448).

J'aimerais faire revivre cela, car les gens vont le rencontrer beaucoup plus souvent sur Windows maintenant que 3.5 s'installe par défaut dans Program Files (ce qui nécessite des privilèges d'administrateur pour être modifié).

J'aime l'option "repli sur --user en cas d'erreur d'autorisation" pour les installations, avec "par défaut sur --user et repli sur le système" lors des désinstallations et peut-être ajouter une option --system ou --system-only pour empêcher le repli. Les utilisateurs exécutant délibérément pip avec des autorisations d'administrateur obtiendront une installation système comme prévu, et actuellement les utilisateurs sans autorisation obtiendraient une erreur, donc je ne pense pas qu'il y ait de problèmes de rétrocompatibilité ici.

Mon objectif est qu'un utilisateur non informé puisse faire pip install spam; python -c "import spam" sans erreur (mais peut-être un avertissement lors d'une nouvelle tentative avec --user ).

J'y ai pensé ces derniers temps, surtout depuis que #2403 et #2401 ont été ouverts récemment, ce qui m'a fait penser à l'utilisation de sudo pip install et à la façon dont cela peut souvent casser les systèmes en dehors des seuls problèmes d'autorisations.

À cette fin, je me demande si le meilleur objectif final n'est pas simplement que --user est la valeur par défaut, pas de vérification magique des autorisations, et ajoute un nouveau drapeau comme --global , --system , ou --no-user qui restaurera le comportement précédent. C'est plus facile à expliquer aux gens car il aura le même comportement, peu importe comment/où les choses sont installées.

Maintenant, si nous décidons que c'est la voie que nous voulons suivre, il reste le problème de savoir comment en arriver là à partir de là où nous en sommes aujourd'hui. Évidemment, quel que soit le moment où nous changerons, la valeur par défaut sera un changement assez important, nous aurons donc besoin d'un délai assez long. Je pense que si nous décidons de suivre cette voie, la meilleure façon de procéder serait de continuer à conserver l'option --user , d'ajouter une nouvelle option comme --global , puis si l'une ou l'autre l'autre option n'est pas configurée, faites la magie de vérification des autorisations dont nous avons parlé et si la magie a décidé d'utiliser le comportement --global , nous déclencherons un avertissement de dépréciation très fort. Cet avertissement de dépréciation durerait beaucoup plus longtemps que nos autres dépréciations que nous avons émises, car il s'agirait d'un changement de comportement assez important. Je pense que nous voudrions également ajouter une option qui désactiverait le repli magique et mettrait en œuvre le comportement futur afin que les gens puissent obtenir ce comportement aujourd'hui.

Une autre question importante est que devons-nous faire si nous détectons que le Python dans lequel nous installons n'a pas de sites utilisateur activés. Dans ce cas, je dirais simplement que --user est une erreur et pour ces Pythons, nous allons simplement revenir à --global par défaut. Cela couvrirait le virtualenv/venv je crois automatiquement, et si quelqu'un veut un environnement isolé "plus lourd" utilisant des Pythons entièrement compilés, il peut simplement patcher site.py afin qu'il définisse ENABLE_USER_SITE à False en haut du fichier.

+1, et je voterais pour --system.

Je noterai, et je suis sûr que vous allez adorer, que la valeur par défaut d'Ubuntu a changé :

https://launchpad.net/ubuntu/+source/python-pip/1.5.6-4ubuntu1

Le 09 février 2015, à 16h41, Donald Stufft a écrit :

À cette fin, je me demande si le meilleur objectif final n'est pas simplement que --user soit le
par défaut, pas de vérification magique des autorisations et ajoutez un nouveau drapeau comme --global ,
--system , ou --no-user qui restaurera le comportement précédent. Ce
est plus facile à expliquer aux gens puisqu'il aura le même comportement peu importe
comment/où les choses sont installées.

Je pense que --system est faux car cela ne s'applique vraiment qu'à certains Pythons. Cela ne s'applique pas à :

  • Python sur Windows
  • pyenv a installé Pythons
  • Conda a installé Pythons
  • Pythons installés par Nix
  • Pythons compilés personnalisés.

Il s'applique _uniquement_ sur les systèmes *nix où le Python se trouve être livré par le système. J'ai l'impression que --global est un bien meilleur nom pour ce drapeau.

Et FML, pourquoi Debian/Ubuntu ressent-il le besoin d'ajouter constamment des correctifs aléatoires qui cassent les cas d'utilisation attendus ?

Donc, si le correctif Ubuntu est annulé, quel est le délai pour que cela soit corrigé ici ? Une semaine/un mois/3 mois/6 mois/un an... ?

Cela dépend de ce que vous entendez par fixe.

En supposant un instant que nous utilisions l'idée que j'avais il y a 2 messages (qui doit encore être approuvée par les autres développeurs de pip), nous pourrions probablement obtenir assez rapidement le plan de transition où ce qui suit est vrai :

  • Lorsque --user est passé, nous installons _toujours_ dans les packages du site utilisateur.
  • Lorsque --global (ou autre) est passé, nous installons _toujours_ dans les packages du site global.
  • Lorsque ni l'un ni l'autre n'est passé, nous implémentons une méthode de secours qui :

    • Détecte si nous sommes dans un environnement virtuel et si c'est le cas agit comme si --global était passé.

    • Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si --global avait été passé.

    • Détecte si l'utilisateur effectif n'a pas les droits d'écriture sur sys.path , et s'il n'agit pas comme si --user avait été passé.

    • Enfin, si toutes les autres méthodes de détection échouent, agissez comme si --global était passé et imprimez un avertissement d'obsolescence indiquant qu'à un moment donné dans le futur, le comportement de celui-ci changera et qu'il s'installera à la place dans --user .

Cela n'empêchera pas quelqu'un de faire sudo pip install foo dans son système Python, mais il affichera un avertissement indiquant qu'à un moment donné, cela signifiera --user et leur dira de commencer explicitement à utiliser --global . Une fois que ce qui précède a été publié pendant suffisamment longtemps, nous pourrions alors supprimer le chemin de code obsolète et le simplifier pour qu'il soit simplement :

  • Lorsque --user est passé, nous installons _toujours_ dans les packages du site utilisateur.
  • Lorsque --global (ou autre) est passé, nous installons _toujours_ dans les packages du site global.
  • Lorsqu'aucune option n'est transmise, nous implémentons une méthode de secours qui :

    • Détecte si nous sommes dans un environnement virtuel et si c'est le cas agit comme si --global était passé.

    • Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si --global avait été passé.

    • Utilise enfin --user par défaut.

Cependant, passer du premier comportement au second comportement va avoir une chronologie assez longue. Cela va être un changement vraiment majeur qui va casser des choses pour n'importe quel logiciel (tel que sel, chef, marionnette) ou script de déploiement (comme des scripts Fabric personnalisés intégrés dans des milliers de projets à travers le monde) qui s'attend à ce que sudo pip install <foo> va s'installer dans le Python global. Nous devrons donner un long délai aux utilisateurs pour voir l'avertissement et modifier leur logiciel et leurs scripts pour passer un indicateur explicite --global s'ils ont réellement besoin de ce comportement.

Je pense que le plan suggéré par Donald est bon, bien que si l'équipe pip décide d'adopter cette approche, nous devrions également déposer un problème de blocage de version 3.5 avec CPython pour que le répertoire de scripts par utilisateur soit ajouté au chemin sous Windows avec le global une. Si 3.5 ajoute cela avec le passage à l'installation dans Program Files par défaut, nous devrions obtenir le comportement souhaité d'installation sans autorisations d'administrateur continuant à "fonctionner simplement".

La possibilité de modifier l'emplacement d'installation par défaut via les fichiers de configuration pip peut également être utile, permettant aux utilisateurs d'opter pour "par utilisateur par défaut" sur leurs propres systèmes, même si la valeur par défaut n'a pas encore changé. (par exemple "default-install=user" vs "default-install=global")

@dstufft : Je suis heureux de donner un coup de main pour mettre en œuvre votre proposition comme indiqué sur le bogue ubuntu si vous avez besoin de moi. Une fois que nous aurons ce comportement dans le coffre, je rétroporterai et remplacerai le correctif Ubuntu actuel par celui-ci bien sûr.

Tenez-moi au courant si vous avez besoin d'aide.

Je suis +1 sur le plan de @dstufft . J'irais pour --global comme nom, pour les raisons indiquées. Nous sommes assis sur la clôture depuis assez longtemps maintenant, allons-y.

O'n et +1 sur la suggestion de @ncoghlan que Python 3.5 ajoute le répertoire du site utilisateur à PATH sous Windows. Évitons d'autres pierres d'achoppement pour cette transition.

Je suis également +1 pour le plan de @dstufft et +1 pour --global , bien que je m'interroge toujours sur le sudo pip install foo nécessitant --global . Est-il en fait nécessaire que root ait des packages de site utilisateur? Pourrions-nous spécial cas root pour avoir les packages de site désactivés par défaut? (Ce qui ferait fonctionner sudo pip install foo comme il le fait maintenant)

Je n'ai jamais vu personne utiliser --user pour root avec l'état actuel, mais si quelqu'un connaît réellement un tel cas d'utilisation, j'aimerais le savoir.

Une pensée qui m'est venue est de savoir comment le répertoire du site utilisateur fonctionnera-t-il avec plusieurs versions de Python installées ?

Si je fais pip install pytest --user en Python 2.7 et 3.4 (avec Python 3.4 mon Python par défaut), quelle version la commande py.test exécutera-t-elle ? Je soupçonne que les deux installations vont s'écraser, c'est donc une situation "le dernier gagne", ce qui n'est _pas_ bon. De plus, si c'est "le dernier gagne" et que j'installe la version 2.7 après la 3.4, comment pourrais-je résoudre ce problème pour que la 3.4 soit à nouveau la version par défaut?

Et qu'en est-il des désinstallations ? Considérez le scénario suivant (non testé, car j'aurais besoin de configurer une machine propre si je ne voulais pas risquer de casser mon ordinateur portable principal) :

    C:\Apps\Python34\python.exe -m pip install pytest --user
    C:\Apps\Python27\python.exe -m pip install pytest --user
    C:\Apps\Python34\python.exe -m pip uninstall -y pytest

Premièrement, pourquoi la deuxième commande n'a-t-elle pas émis d'avertissement indiquant qu'elle écrasait un fichier existant ? Ou le serait-il? Que ce soit le cas ou non, ai-je des options sur ce qu'il faut faire ?

Deuxièmement, la désinstallation n'échouerait-elle pas parce que la somme de contrôle de py.test.exe ne correspondrait pas à la valeur du fichier RECORD ? Si cela échoue, comment désinstaller ? Si cela n'échoue pas, cela cassera-t-il ma copie Python 2.7 de pytest (en supprimant l'exe) ?

Et enfin (pour l'instant !) Le répertoire des scripts utilisateur ira-t-il avant ou après le répertoire des scripts système dans PATH ? IMO, cela devrait aller après, sinon une installation utilisateur d'un package dans un Python qui n'a pas été demandé par l'utilisateur pour être "le Python par défaut" pourrait remplacer le même package installé dans les packages de site système Python "par défaut".

Hmm, peut-être y a-t-il des questions ouvertes qui doivent être résolues avant que nous apportions ce changement...

Je m'attendrais à ce que les conflits de noms dans le répertoire de script utilisateur Windows partagé soient gérés de la même manière qu'ils sont gérés sur les systèmes POSIX avec leurs répertoires bin partagés : Python 3 n'installerait pas le nom de script non qualifié pour les packages installés, donc le non qualifié nom ferait référence à la version Python 2.

Il en va de même si l'installation système ou l'installation par utilisateur est prioritaire par défaut : placez le répertoire de script utilisateur après celui du système.

"Python 3 n'installerait pas le nom de script non qualifié pour les packages installés" - vous voulez probablement dire que pip et setuptools (sous Python 3) ne le feraient pas, ici? C'est donc un changement pour ces outils ?

Oh, et bof. Ma mémoire musculaire est entraînée à 100% pour taper "pip install foo" à installer dans mon Python par défaut (3.4). Ça va être l'enfer pour se recycler.

De plus, les utilisateurs Windows peuvent choisir si "python" signifie Python 2 ou 3 (via "en faire le Python par défaut" et "Ajouter au PATH") - contrairement aux utilisateurs Unix où le système Python établit les règles. Donc, si je dis que je veux faire de Python 3.5 ma version par défaut, pourquoi "pip" (ou tout autre nom non qualifié) ne devrait-il pas faire référence à cette version ? Il semble bizarre qu'un utilisateur avec uniquement Python 3.5 installé sur Windows ne puisse pas utiliser des noms non qualifiés simplement à cause d'un problème Unix concernant la façon dont le système Python a besoin de noms. (Excuses si ma description des contraintes Unix est inexacte - je ne comprends pas vraiment le problème là-bas). Les personnes qui installent plusieurs versions de Python ont besoin d'une solution, mais cette solution ne devrait pas affecter la majorité qui n'a besoin que d'une seule version.

La réponse la plus simple est peut-être que le répertoire des scripts utilisateur doit être versionné, tout comme le répertoire des packages du site utilisateur.

Oh, et ce débat devrait-il porter sur python-dev plutôt qu'ici, car il s'agit plus généralement du répertoire du site utilisateur?

Rouvrir la discussion sur la conception de la PEP 370 pour le répertoire des scripts par utilisateur Windows sur python-dev serait certainement raisonnable. Il est étrange que les installations de scripts globales sur Windows soient limitées par la version de Python, mais pas les installations de scripts par utilisateur.

Cela contraste avec la situation sur POSIX, qui utilise systématiquement un espace de noms partagé pour les exécutables aux deux niveaux (global ou par utilisateur), de sorte que les conflits de noms sont plus susceptibles d'apparaître au moment de l'installation, plutôt que par l'occultation des noms au moment de l'exécution.

En ce qui concerne la solution générale pour gérer l'installation parallèle, ce serait le commutateur "-m" - de cette façon, vous savez toujours quel Python vous invoquez, plutôt que de deviner le contenu de la ligne shebang d'un script séparé.

Compris concernant -m , mais la dernière fois que cela a été évoqué dans le contexte de la façon de documenter les choses, la forte préférence était que nous devrions traiter pip install foo comme la manière canonique d'installer les choses (avec -m et les commandes versionnées sont traitées comme des exceptions pour les cas spécialisés.

Le manuel de pip ne mentionne même pas d'alternatives (sauf dans le cas de l'utilisation de -m pour mettre à jour pip lui-même sous Windows).

Je recommande -m dans la documentation du package stdlib pour gérer l'invocation de pip lorsque
traitant des installations Python parallèles - c'est le seul style d'invocation qui
fonctionne sur toutes les plates-formes, pour les installations globales, les installations utilisateur et virtuelles
environnements.

Le 9 février 2015, à 19h58, ncoghlan a écrit :

Pouvoir changer l'emplacement d'installation par défaut via les fichiers de configuration pip
peut également être utile, permettant aux gens d'opter pour "par utilisateur par défaut" sur
leurs propres systèmes, même si la valeur par défaut n'a pas changé
encore. (par exemple "default-install=user" vs "default-install=global")

J'aime ça. L'une des choses avec lesquelles nous nous débattons est de savoir comment résoudre
l'approche plus conservatrice d'amont pour migrer vers un --user default, avec
distros objectifs concurrents de rendre le système pip sûr et cohérent avec d'autres
outils. Par exemple

https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1419695
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=725848

Si nous avions un fichier de configuration à l'échelle du système pour sélectionner la valeur par défaut, alors à
moins toutes les machines impliquées seraient identiques, et les distributions ne seraient pas
avoir à porter des deltas laids. Tout ce que nous aurions à faire serait de changer le
fichier de configuration et documentez-le pour nos utilisateurs. Les problèmes qui en résulteraient seraient
à nous de gérer, mais au moins ce serait facile à expliquer.

Je ne pense pas que Debuntu installe actuellement un fichier pip.conf à l'échelle du site (j'aurai
à vérifier).

https://pip.pypa.io/en/latest/user_guide.html#configuration

Une complication : on installe des scripts pip différents pour Python 2 et Python 3,
donc je pense que nous aurions besoin de fichiers de configuration séparés pour les différentes versions de
Python, par exemple /etc/{xdg/pip/}/pip{2,3}.conf ou quelque chose comme ça.

Le 10 février 2015 à 01h24, Paul Moore a écrit :

Une pensée qui m'est venue est de savoir comment le répertoire du site utilisateur fonctionnera avec
plusieurs versions de Python installées ?

Sur Debian/Ubuntu (peut-être tous les *nix ?), nous n'avons pas de collision car le
les bibliothèques sont installées dans ~/.local/lib/pythonX.Y/site-packages

Cependant, nous _obtenons_ des collisions sur ~/.local/bin. Installation d'un package avec un
le script 'foo' utilisant pip install --user foo et pip3 install --user foo
finir par encombrer le script ~/.local/bin/foo.

Un inconvénient de ce changement est que je pense que Fedora est la seule distribution en aval qui ajoute ~/.local/bin à $PATH par défaut (et cela devrait venir avant /usr/bin et /usr/local/bin juste comme les packages de site utilisateur viennent avant les packages de site). Idéalement, les avals pourront modifier leurs systèmes afin que ~/.local/bin soit sur $PATH par défaut.

Le 10 février 2015, à 07h24, Donald Stufft a écrit :

Un inconvénient de ce changement est que je pense que Fedora est le seul en aval
distribution qui ajoute ~/.local/bin à $PATH par défaut (et cela devrait venir
avant /usr/bin et /usr/local/bin tout comme les packages du site utilisateur viennent
avant les forfaits-site). Idéalement, les avals pourront modifier leur
systèmes de sorte que ~/.local/bin soit sur $PATH par défaut.

Oui, mais nous pouvons prendre une décision distincte à ce sujet. (Ou plutôt, en aval
les distributions peuvent le faire.)

(et il devrait venir avant /usr/bin et /usr/local/bin tout comme l'utilisateur
les packages de site viennent avant les packages de site)

Hmm, @ncoghlan vient de dire le contraire, que (sur Windows, en particulier
contexte) le répertoire des scripts utilisateur doit être _après_ celui du système. Lequel
Je suis d'accord tant que le répertoire des scripts utilisateur n'est pas versionné. Si c'est
versionné, je suis moins concerné. Mais cela reflète probablement le fait que
Les utilisateurs de Windows n'ont jamais eu à endurer des conflits de scripts non versionnés et
des monstruosités comme pip2/pip3, comme les utilisateurs d'Unix ont ;-)

Oh, et le truc du script clobbering est un problème plus général qui n'est pas vraiment lié à --user exactement. Le même problème existe partout sauf les installations de Windows --global . Je pense que la solution à ce problème est une préoccupation/problème secondaire que nous devrions résoudre séparément de cette question.

Alors réflexions actuelles :

  • Je pense qu'il y a un accord sur l'idée générale que j'ai postée plus tôt, donc je pense que nous voudrons aller de l'avant avec quelque chose comme ça.
  • Nous allons utiliser le drapeau --global .
  • Nous voulons probablement une sorte d'avertissement si nous installons dans --user et que ~/.local/bin n'est pas sur le $PATH .
  • Nous aurons besoin d'une sorte d'option default-install qui désactivera essentiellement le comportement de secours et se contentera de coder en dur soit --global soit --user .
  • Depuis pip 6.0, nous avons des fichiers de configuration spécifiques à la machine situés dans /etc/ , mais ils ne sont pas spécifiques à la version de Python qui exécute pip. Je pense que c'est une bonne fonctionnalité bien que quelque peu distincte également (et pourrait également aller de pair avec la résolution du problème d'écrasement du script).

Je vois encore une question ouverte majeure : à long terme, que voulons-nous qu'il se passe lorsque quelqu'un fait sudo pip install foo ou plutôt, si quelqu'un a la permission d'écrire dans le répertoire site-packages ?

Les options auxquelles je peux penser sont :

  1. Installer dans --global . Il s'agit de l'option la plus rétrocompatible et représente probablement ce que les utilisateurs attendent lorsqu'ils tapent cela. Cependant, il a l'inconvénient de déranger (silencieusement) le Python global, ce qui, sur de nombreux systèmes, peut provoquer des pannes de systèmes.
  2. Installez dans --user , cela protégera des systèmes cassés (je pense?) Mais je ne pense pas que quiconque s'attendrait à ce que l'utilisateur root obtienne une installation /root/.local/ .
  3. Sortez simplement l'erreur et demandez à l'utilisateur de sélectionner manuellement --user ou --global .
  4. Choisissez l'une des deux premières options, mais fournissez un commutateur que les distributions peuvent activer en /etc/ qui activera la troisième option.

La quatrième option est peut-être la meilleure, mais je pense que nous devrions d'abord essayer de sélectionner l'une des autres options si nous pouvons trouver une sorte de solution qui fonctionne de la même manière sur toutes les plates-formes/scénarios et qui a du sens sur toutes comme je préférerait avoir un comportement cohérent entre plates-formes si possible.

J'ai l'impression que la troisième option est probablement mauvaise, car "j'ai l'autorisation d'écriture" sera le scénario selon lequel n'importe qui sur Windows est sur une version antérieure à Python 3.5, ou toute personne qui utilise Conda, ou toute personne qui utilise pyenv. L'erreur semble être la mauvaise chose à faire dans tous ces cas et est assez peu conviviale pour démarrer.

Donc, je suppose qu'entre 1 et 2, cela se résume vraiment à la mauvaise pratique que nous pensons qu'il est pour les gens de (conceptuellement) faire sudo pip install --global foo . Sur Windows, Conda, pyenv, etc., j'ai l'impression que la réponse est "nous ne pensons pas que ce soit une mauvaise pratique du tout". Sur *nix, j'ai l'impression que la réponse est peut-être "les utilisateurs devraient être autorisés à faire ce qu'ils veulent de leur système, mais nous devrions fournir des rails pour les éloigner des "mauvaises" choses".

Donc, en y réfléchissant davantage, je pense que je devrais choisir la première option comme étant la bonne option pour nous. Cela résout plus ou moins les problèmes de compatibilité descendante puisque le comportement que nous changerions vraiment est que si vous tapez pip install foo sans autorisation d'installation dans ces répertoires globaux, vous installerez dans --user au lieu de remonter une erreur. Je pense qu'il est peu probable que quelqu'un dépende vraiment du pip qui génère une erreur dans ce cas. Je pense aussi que pip install --user en tant qu'utilisateur root est peu susceptible d'être ce que quiconque attend ou veut et c'est vraiment juste un pistolet pour les utilisateurs.

Alors ma proposition mise à jour serait:

  • Lorsque --user est passé, nous installons toujours dans les packages du site utilisateur.
  • Lorsque --global est passé, nous installons toujours dans les packages du site global.
  • Lorsque ni l'un ni l'autre n'est passé, nous implémentons une méthode de secours qui :

    1. Détecte si nous sommes dans un environnement virtuel et si c'est le cas agit comme si --global était passé.

    2. Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si --global avait été passé.

    3. Regarde default-install et si cela existe, utilise --user ou -global en fonction de celui-ci.

    4. Détecte si l'utilisateur effectif ne dispose pas d'autorisations d'écriture sur les packages de sites globaux et s'il n'agit pas comme si --user avait été transmis.

    5. Enfin, si toutes les autres méthodes de détection échouent, agissez comme si --global était passé.

Cela signifierait qu'il n'y a pas de période d'obsolescence et que l'on s'attend à ce qu'en l'absence de --user ou --global , nous essaierons de faire la meilleure estimation en fonction des capacités du Python dans lequel nous exécutons , l'utilisateur effectif et toute méthode d'installation par défaut configurée.

(et il devrait venir avant /usr/bin et /usr/local/bin tout comme l'utilisateur
les packages de site viennent avant les packages de site)

Hmm, @ncoghlan vient de dire le contraire, que (sur Windows, en particulier
contexte) le répertoire des scripts utilisateur doit être _après_ celui du système. Lequel
Je suis d'accord tant que le répertoire des scripts utilisateur n'est pas versionné. Si c'est
versionné, je suis moins concerné. Mais cela reflète probablement le fait que
Les utilisateurs de Windows n'ont jamais eu à endurer des conflits de scripts non versionnés et
des monstruosités comme pip2/pip3, comme les utilisateurs d'Unix ont ;-)

Je ne pense même pas aux noms de script qui se heurtent. Je pense juste qu'il est complètement faux que notre variable $PATH agisse différemment de sys.path . Autant que je sache, la commande sys.path est : stdlib > packages de site utilisateur > packages de site global. Je pense que ce serait vraiment déroutant si la commande some-script était répertoire bin global > répertoire bin utilisateur alors que python -m some-script était packages de site utilisateur > packages de site global.

S'il y a un problème avec les répertoires de script (et versionnés vs non versionnés), je pense que nous devrions résoudre ce problème, mais que ce n'est pas très pertinent pour l'ordre dans lequel ils devraient être, car j'ai envie de tout autre chose que de correspondre à ce que sys.path fait est super faux.

Bon point, nous devrions supposer (et recommander) que $PATH suit sys.path, avec (en termes Windows) C:PythonXY avant %APPDATA%PythonXYScripts avant C:PythonXYScripts. Je noterai cela sur le fil python-dev.

La dernière proposition de Donald me semble bonne (la même que celle d'origine plus tous les détails importants que j'ai omis :) ). Je suis également d'accord à 100 % avec le paragraphe "Donc, pensez-y davantage...".

Quant à la configuration de PATH sous Windows, cela va être presque impossible. Un programme d'installation à l'échelle du système ne peut configurer que des variables d'environnement à l'échelle du système et ne peut pas inclure d'extensions. Vous ne pouvez donc pas définir de chemins différents pour chaque utilisateur. (Le programme d'installation par utilisateur peut le faire, mais dans ce cas, --global réussira et il n'y a donc pas besoin.)

De plus, en raison de la gestion PATH défectueuse de Windows, les paramètres à l'échelle du système _toujours_ battent les paramètres par utilisateur. Cela a conduit à ma demi-suggestion il y a quelque temps (sur python-dev, IIRC) sur l'utilisation du lanceur py.exe pour les scripts non versionnés, de sorte que pip.exe ira toujours au dernier système ou utilisateur Python plutôt que le celui qui l'a installé, et (par exemple) pip.exe -3.5 permettrait une sélection de version spécifique.

La seule façon de faire en sorte que cela fonctionne vraiment est que le programme d'installation de Python commence à installer des fichiers de commandes pour configurer PATH sur demande (et peut-être un raccourci qui exécute le fichier de commandes). Ainsi, la première chose que les utilisateurs tapent est activate-py35 , puis leur PATH est configuré correctement pour 3.5. Je suis très déchiré à ce sujet, car je ne veux pas entrer dans la situation vcvarsall.bat, mais en même temps, ce sera génial pour les scripts qui font actuellement des hypothèses sur les emplacements d'installation ou essaient de passer par le registre pour le trouver.

et peut-être un raccourci qui exécute le fichier batch

Dans mon esprit, il s'agit d'un raccourci "Python 3.5 (32-bit) Command Prompt". Les utilisateurs de Visual Studio doivent reconnaître le parallèle.

Je n'en sais pas assez sur Windows pour comprendre pleinement les implications de tout cela, mais je me sens assez mal à l'idée de revenir à une situation où pip install foo qui installe un script foo ne peut pas être immédiatement exécuté en tant que foo sur la ligne de commande. Si nous installons sur --user et que ce n'est pas sur leur chemin par défaut, cela me semble être une régression assez importante.

Je ne suis pas sûr de comprendre exactement comment l'utilisation py.exe pour les scripts non versionnés fonctionnerait dans la pratique et si cela résoudrait ou non le problème. Je ne suis pas personnellement lié à la création de scripts exactement comme nous le sommes aujourd'hui, donc si cela fonctionne, je pense que nous pouvons peut-être le faire, mais je devrais mieux comprendre les implications avant de pouvoir donner mon +1 dessus.

Quant à la configuration de PATH sous Windows, cela va être presque impossible. Un programme d'installation à l'échelle du système ne peut configurer que des variables d'environnement à l'échelle du système et ne peut pas inclure d'extensions. Vous ne pouvez donc pas définir de chemins différents pour chaque utilisateur.

Oh, beurk. J'avais oublié ça.

et peut-être un raccourci qui exécute le fichier batch
Dans mon esprit, il s'agit d'un raccourci "Python 3.5 (32-bit) Command Prompt". Les utilisateurs de Visual Studio doivent reconnaître le parallèle.

... ce qui est horrible pour ceux d'entre nous qui utilisent par défaut Powershell pour tout.

mais je me sens assez mal à l'idée de revenir à une situation où pip install foo qui installe un script foo ne peut pas être exécuté immédiatement en tant que foo sur la ligne de commande.

D'accord. Ce serait une mauvaise régression, et il faut y remédier. J'aimerais juste que quelqu'un puisse penser à un moyen :-)

Je ne suis pas sûr de comprendre exactement comment l'utilisation de py.exe pour les scripts non versionnés fonctionnerait en pratique

Je pense que le point (qui n'est que quelque peu lié à py.exe ) est que le wrapper exe, plutôt que d'invoquer un interpréteur Python spécifique et codé en dur comme il le fait actuellement, devrait choisir dynamiquement l'interpréteur en fonction de "ce que est la valeur par défaut" d'une manière ou d'une autre (le registre, le fichier ini py.exe , tout ce que Python %PATH% vous donne, ...). Je ne sais pas comment cela aiderait, cependant, car nous aurions toujours besoin d'un répertoire de scripts utilisateur versionnés (pour éviter que les fichiers ne s'écrasent les uns les autres ou que les fichiers ne soient exécutés avec des interpréteurs sur lesquels le paquet n'est pas installé) et nous le ferions toujours Je ne peux pas le mettre au bon endroit dans %PATH%.

... ce qui est horrible pour ceux d'entre nous qui utilisent par défaut Powershell pour tout.

Je viens de l'essayer, et je peux facilement créer des fichiers activate-py35.bat et activate-py35.ps1 qui se ressemblent et se comportent de manière identique (c'est-à-dire que tout le monde peut écrire activate-py35 et mettre à jour les chemins). Toujours pas idéal, mais peut-être le meilleur d'une mauvaise situation.

Je ne suis pas sûr de comprendre exactement comment l'utilisation de py.exe pour les scripts non versionnés fonctionnerait en pratique

Je pense que le point (qui n'est que quelque peu lié à py.exe ) est que le wrapper exe, plutôt que d'invoquer un interpréteur Python spécifique et codé en dur comme il le fait actuellement, devrait choisir dynamiquement l'interpréteur en fonction de "ce que est la valeur par défaut" en quelque sorte

Le "d'une manière ou d'une autre" est l'endroit où py.exe entre en jeu - les mêmes règles doivent être utilisées. Si le lanceur a été mis à jour pour vérifier son propre nom, alors au lieu de lancer python.exe , il pourrait essayer de lancer 'scripts\\{}{}.{}.exe'.format(argv[0], major_version, minor_version) (avec l'extension appropriée sur argv[0] , etc.) à la place. Ensuite, les installateurs doivent utiliser un fichier différent pour le lanceur non versionné de celui entièrement versionné (qui serait inchangé à partir d'aujourd'hui), mais ce fichier serait simplement le py.exe normal avec un nouveau nom. (Cela aurait pu être encore plus simple à l'époque des fichiers pip-script.py , mais maintenant qu'ils ont disparu...)

Mais comme vous le dites, PATH est toujours le problème. Je n'ai pas de bonnes solutions, et même pas beaucoup de mauvaises solutions. Les variables d'environnement sont vraiment destinées aux administrateurs ou aux utilisateurs à configurer, pas aux installateurs.

Nous pouvons ajuster la façon dont nous installons les scripts pour améliorer l'expérience utilisateur. Tout est un équilibre, le fichier combiné .exe et .py a rendu les choses plus agréables pour les utilisateurs puisqu'il n'y a que le fichier singulier .exe . Cependant, j'ai l'impression qu'obtenir la meilleure histoire pour pip install foo && foo est plus important que cette chose en particulier, donc si nous devons séparer à nouveau les .exe et les .py , je pense que c'est un bon compromis pour une bonne réponse.

La séparation .exe / .py est le moindre des problèmes :)

En fait, je me prépare (ou j'accepte à contrecœur ?) L'idée activate-py35 . Je n'ai jamais été fan du programme d'installation ajoutant Python à PATH, et la commande py -m pip n'a pas vraiment gagné en popularité (et cela ne fonctionnerait pas non plus pour, disons, Sphinx). Je vais rédiger une description plus détaillée de la façon dont activate-py pourrait fonctionner et la publier sur python-dev pour voir si elle obtient une traction.

Ces fichiers activate-whatever seraient-ils similaires à ceux de l'environnement virtuel ? Sauf qu'au lieu d'ajouter un environnement virtuel à $PATH , il ajoute les vrais Pythons ?

Oui, à peu près identiques. Sur python-dev, je viens de suggérer qu'ils prendraient un paramètre -x.y , le passeraient à py.exe et utiliseraient sysconfig pour obtenir les chemins.

D'accord. Je n'ai pas d'opinion sur la gravité de la situation pour les utilisateurs de Windows, car je n'en suis pas un. Cela ne semble pas absolument horrible (peut-être ?) mais c'est à peu près aussi loin que mes connaissances Windows peuvent me mener.

Le 10 février 2015, à 08h02, Donald Stufft a écrit :

Oh, et le truc du script clobbering est un problème plus général qui n'est pas
vraiment lié à --user exactement. Le même problème existe partout
sauf les installations Windows --global . Je pense que la solution à ce problème est
une préoccupation/problème secondaire que nous devrions résoudre séparément de ce problème.

D'accord.

Nous allons utiliser le drapeau --global .

+1

Nous voulons probablement une sorte d'avertissement si nous installons dans --user et
~/.local/bin n'est pas sur le $PATH .

+1, peut-être avec une option de configuration pour supprimer l'avertissement ?

Nous voudrons une sorte d'option default-install qui sera essentiellement
désactivez le comportement de secours et codez simplement en dur soit --global soit
--user .

+1

Depuis pip 6.0, nous avons des fichiers de configuration spécifiques à la machine situés dans /etc/
cependant ceux-ci ne sont pas spécifiques à la version de Python qui s'exécute
pépin. Je pense que c'est une bonne fonctionnalité bien que quelque peu distincte aussi (et
pourrait également aller de pair avec la résolution du problème d'écrasement du script).

Je suggérerais un ordre de recherche tel que:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

enraciné d'abord (?) dans /etc/xdg/pip puis /etc, où XY est bien sûr le
numéro de version majeur.mineur. Le premier trouvé, gagne.

Je vois encore une grande question ouverte : à long terme, que voulons-nous qu'il se passe lorsque
quelqu'un fait sudo pip install foo ou plutôt, si quelqu'un a la permission de
écrire dans le répertoire site-packages ?

Veuillez noter qu'il n'y a pas qu'un seul répertoire "site-packages". Par exemple,
sur Debian/Ubuntu, nous ne voulons pas que sudo pip install _jamais_ s'installe dans
/usr/lib, mais uniquement /usr/local/lib. Et n'oubliez pas, c'est ici les dist-packages
pas site-packages (sauf dans ~/.local car $reasons).

C'est vraiment un point important qui est parfois oublié (même par moi).
Donald le décrit le mieux quand il dit qu'il y a un répertoire site-local et un
répertoire local du fournisseur. Sur Debian, site-local est
/usr/lib/pythonX.Y/dist-packages et aucune commande pip ne devrait jamais toucher à cela,
tandis que vendor-local est /usr/local/lib/pythonX.Y/dist-packages et c'est un
cas d'utilisation documenté et populaire pour certains administrateurs système pour installer pip
dans ce répertoire.

Donc, ce que je suggérerais, puisque nous sommes déjà sur le chemin du fichier de configuration, est de
rendez-les configurables, par exemple

  • global_install_directory
  • global_install_as_sudo (vrai/faux)
  1. Installer dans --global . C'est l'option la plus rétrocompatible
    et représente probablement ce que les utilisateurs attendent lorsqu'ils tapent cela. Cependant il a
    l'inconvénient qu'il va (silencieusement) gâcher le Python global, qui sur de nombreux
    systèmes peuvent causer des systèmes cassés.

Avec la configurabilité ci-dessus, cela serait totalement compatible avec Debian.
Les super-utilisateurs de Debian s'attendent à ce que sudo pip install entre dans
/usr/local/lib/pythonX.Y/dist-packages. Je ne dirais pas que "ça gâche le
system" car cela ne casse pas le gestionnaire de paquets, et même s'il peut
remplacer les packages installés par le système (qui résident dans
/usr/lib/pythonX.Y/dist-packages), il le fait de manière définie et documentée.

  1. Installez dans --user , cela protégera des systèmes cassés (je pense ?)
    mais je ne pense pas que quiconque s'attendrait à ce que l'utilisateur root obtienne un
    /root/.local/ installation.

D'accord, ce serait inattendu.

  1. Sortez simplement l'erreur et demandez à l'utilisateur de sélectionner --user ou
    --global manuellement.

Je serais d'accord avec ça, mais voir le commutateur de configuration ci-dessus.

  1. Choisissez l'une des deux premières options, mais fournissez un commutateur que les distributions peuvent
    remettez /etc/ qui activera la troisième option.

Hé, quelle bonne option !

La quatrième option est peut-être la meilleure, mais je pense que nous devrions essayer de
sélectionnez d'abord l'une des autres options si nous pouvons trouver une solution
qui fonctionne de la même manière sur toutes les plates-formes/scénarios et qui a du sens sur chacun d'eux
car je préférerais avoir un comportement cohérent entre les plates-formes si possible.

Je suis d'accord avec un comportement différent, défini par la plate-forme, si disons, pip avait un
--option d'exécution à sec qui indiquerait au moins à l'utilisateur exactement ce qu'il se passait
faire et où.

J'ai l'impression que la troisième option est probablement mauvaise, car "j'ai écrit
autorisation" va être le scénario que n'importe qui sur Windows est sur le pré
Python 3.5, ou toute personne qui utilise Conda, ou toute personne qui utilise pyenv. Erreur
semble être la mauvaise chose à faire dans tous ces cas et est quelque chose d'utilisateur
hostile pour démarrer.

Je serais heureux si la configuration par défaut était d'autoriser --global install si vous
avoir l'autorisation. Je ne pense même pas que Debian le changerait (peut-être que d'autres l'ont fait
une opinion différente, mais au moins cela nous donne des options).

Donc, je suppose qu'entre 1 et 2, cela dépend vraiment de la gravité de la pratique
nous pensons que c'est aux gens de faire (conceptuellement) sudo pip install --global foo .

Sur Debian, c'est un cas d'utilisation attendu, tant qu'il va à /usr/local/lib.
Il ne peut pas accéder à /usr/lib.

(Tout cela décrit un comportement extérieur à venv BTW.)

  • Lorsque --user est passé, nous installons toujours dans les packages du site utilisateur.

+1

  • Lorsque --global est passé, nous installons toujours dans le site global
  • paquets.

Packages _vendor_ globaux == +1, packages de site globaux == -1.

  • Lorsque ni l'un ni l'autre n'est passé, nous implémentons une méthode de secours qui :

    1. Détecte si nous sommes dans un environnement virtuel et si c'est le cas agit comme si

      --global a été passé.

+1, bien que je répète que ce répertoire à l'intérieur d'un venv est nommé
/lib/pythonX.Y/site-packages

  1. Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si
    --global a été passé.

Hmm, je ne suis pas sûr de celui-ci.

  1. Regarde default-install et si cela existe utilise --user ou
    -global en fonction de cela.

+1

  1. Détecte si l'utilisateur effectif ne dispose pas d'autorisations d'écriture sur global
    packages de site, et s'ils n'agissent pas comme si --user avait été passé.

+1

  1. Enfin, si toutes les autres méthodes de détection échouent, agissez comme si --global
    a été réussi.

Pas sûr non plus.

Cela signifierait qu'il n'y aurait pas de période d'amortissement et que l'on s'attend à ce que dans le
absence de --user ou --global nous essaierons de faire la meilleure estimation en fonction
sur les capacités du Python que nous utilisons, l'utilisateur effectif et
toute méthode d'installation par défaut configurée.

Sonne comme un objectif raisonnable.

Pour être clair, quand je parle de "packages de sites globaux", je veux dire principalement "tout ce que distutils nous dit d'installer des choses globalement". Étant donné que Python lui-même n'a pas de distinction entre "fournisseur local" et "site local", ce sera le même répertoire sur tout aval qui ne corrige pas son Python. Sur Debian, cependant, il s'agira en fait d'un répertoire dist-packages et "global" signifie en fait "site local". Ce n'est pas quelque chose que pip doit faire quoi que ce soit de spécial pour le prendre en charge, car cela est pris en charge par les correctifs de Debuntu pour Python.

En d'autres termes, pip s'installe déjà sur /usr/local/../dist-packages/ sur Debuntu puisque Debuntu a corrigé distutils pour prendre en charge cette distinction. La seule fois où pip jouerait avec /usr/../dist-packages/ sans que l'utilisateur ne passe un indicateur quelconque, c'est que pip désinstallerait des fichiers à partir de là (parce que pip ne voit pas ce répertoire comme spécial, il le voit juste comme une chose sur sys.path ). Debian a cependant corrigé pip pour empêcher cette désinstallation à partir de là, et je pense que la prise en charge réelle de cela dépend de l'obtention d'une prise en charge réelle des packages de site "fournisseur local" dans Python en amont.

Nous voulons probablement une sorte d'avertissement si nous installons dans --user et ~/.local/bin n'est pas sur le $PATH

Dans quelle mesure cet avertissement est-il susceptible d'être fragile ? Serait-il converti en chemin absolu? Serait-il insensible à la casse sur les systèmes de fichiers insensibles à la casse ? Traiterait-il et/comme équivalent sous Windows ? Qu'en est-il des liens symboliques ?

Si vous installez un paquet qui n'installe aucun script, l'avertissement n'est de toute façon pas pertinent.

Personnellement, je pense qu'un avertissement fera probablement plus de mal que de bien.

Nous voulons probablement une sorte d'avertissement si nous installons dans --user et
~/.local/bin n'est pas sur le $PATH .

+1, peut-être avec une option de configuration pour supprimer l'avertissement ?

Nous pourrions simplement lui faire utiliser un avertissement Python pour que les gens puissent simplement se taire
en utilisant les avertissements Python intégrés. Si nous ressentons le besoin de le faire taire à
tous.

Depuis pip 6.0, nous avons des fichiers de configuration spécifiques à la machine situés dans /etc/
cependant ceux-ci ne sont pas spécifiques à la version de Python qui s'exécute
pépin. Je pense que c'est une bonne fonctionnalité bien que quelque peu distincte aussi (et
pourrait également aller de pair avec la résolution du problème d'écrasement du script).

Je suggérerais un ordre de recherche tel que:

  • pipX.Y.conf
  • pipX.conf
  • pip.conf

enraciné d'abord (?) dans /etc/xdg/pip puis /etc, où XY est bien sûr le
numéro de version majeur.mineur. Le premier trouvé, gagne.

Divisez ceci en # 2417 car je pense que ce n'est que tangentiellement lié à cela
discussion.

Je vois encore une grande question ouverte : à long terme, que voulons-nous qu'il se passe lorsque
quelqu'un fait sudo pip install foo ou plutôt, si quelqu'un a la permission de
écrire dans le répertoire site-packages ?

Veuillez noter qu'il n'y a pas qu'un seul répertoire "site-packages". Par exemple,
sur Debian/Ubuntu, nous ne voulons pas que sudo pip install _jamais_ s'installe dans
/usr/lib, mais uniquement /usr/local/lib. Et n'oubliez pas, c'est ici les dist-packages
pas site-packages (sauf dans ~/.local car $reasons).

C'est vraiment un point important qui est parfois oublié (même par moi).
Donald le décrit le mieux quand il dit qu'il y a un répertoire site-local et un
répertoire local du fournisseur. Sur Debian, site-local est
/usr/lib/pythonX.Y/dist-packages et aucune commande pip ne devrait jamais toucher à cela,
tandis que vendor-local est /usr/local/lib/pythonX.Y/dist-packages et c'est un
cas d'utilisation documenté et populaire pour certains administrateurs système pour installer pip
dans ce répertoire.

Donc, ce que je suggérerais, puisque nous sommes déjà sur le chemin du fichier de configuration, est de
rendez-les configurables, par exemple

  • global_install_directory
  • global_install_as_sudo (vrai/faux)

pip ne les contrôle pas vraiment (je veux dire, évidemment au haut niveau, il le fait
car c'est lui qui déplace les fichiers), ils proviennent de distutils/sysconfig.

Je pense que pip ne devrait probablement jamais toucher un répertoire fournisseur local à moins que
une sorte de drapeau a été donné comme --vendor qui permettrait aux fournisseurs d'utiliser
pip dans leur chaîne de construction. Ce concept n'existe pas vraiment en dehors de debuntu
en ce moment et leurs correctifs gèrent déjà cela, donc je ne pense pas que ce soit super
pertinent à cette discussion sauf pour noter que quand je dis
"forfaits de sites mondiaux", je voulais dire /usr/local/.../dist-packages sur Debubuntu
et les packages "site-local" à un moment donné si Python accepte le Debuntu
système en amont.

  1. Installer dans --global . C'est l'option la plus rétrocompatible
    et représente probablement ce que les utilisateurs attendent lorsqu'ils tapent cela. Cependant il a
    l'inconvénient qu'il va (silencieusement) gâcher le Python global, qui sur de nombreux
    systèmes peuvent causer des systèmes cassés.

Avec la configurabilité ci-dessus, cela serait totalement compatible avec Debian.
Les super-utilisateurs Debian s'attendent à ce que sudo pip install entre dans
/usr/local/lib/pythonX.Y/dist-packages. Je ne dirais pas que "ça gâche le
system" car cela ne casse pas le gestionnaire de paquets, et même s'il peut
remplacer les packages installés par le système (qui résident dans
/usr/lib/pythonX.Y/dist-packages), il le fait de manière définie et documentée.

Oui, "désordre le système" peut être trop dur. Surtout je veux dire que
sudo pip install foo peut casser des choses si le système dépend de foo et
vous installez une version incompatible des choses. Cependant, ce même cas est valable
true pour pratiquement tout ce que vous installez dans`/usr/local``.

  • Lorsque --global est passé, nous installons toujours dans le site global
  • paquets.

Packages _vendor_ globaux == +1, packages de site globaux == -1.

Vous voulez dire cela dans l'autre sens, n'est-ce pas ?

  • Lorsque ni l'un ni l'autre n'est passé, nous implémentons une méthode de secours qui :

    1. Détecte si nous sommes dans un environnement virtuel et si c'est le cas agit comme si

      --global a été passé.

+1, bien que je répète que ce répertoire à l'intérieur d'un venv est nommé
/lib/pythonX.Y/site-packages

Oui, encore une fois, nous demandons simplement à Python où se trouve ce répertoire, nous ne le calculons pas
nous-mêmes, donc "où se trouve ce répertoire" est une chose venv/virtualenv.

  1. Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si
    --global a été passé.

Hmm, je ne suis pas sûr de celui-ci.

Je ne pense pas qu'il y ait un moyen de contourner cela, si les packages de site utilisateur sont désactivés, je
ne pense pas que nous devrions installer là-dedans parce que nous n'avons aucun moyen de savoir
si cette désactivation signifie qu'il n'y a pas de packages de site utilisateur, ou pourquoi. Nous ne pouvons que
supposons qu'il n'y en a pas.

  1. Enfin, si toutes les autres méthodes de détection échouent, agissez comme si --global
    a été réussi.

Pas sûr non plus.

Cela se résume essentiellement à :

Si nous n'avons pas trouvé de raison, nous devrions utiliser --user, comme un drapeau --user, ou
n'ayant pas les permissions d'écrire dans le répertoire, alors ne l'utilisez pas. Ce
est ce qui gardera sudo pip install foo sans un drapeau --global
travaillant. Cela signifie également que c'est la règle la plus importante pour ne pas enfreindre
logiciel fonctionnel qui s'attend à ce que sudo pip install foo agisse de cette façon.

Nous voulons probablement une sorte d'avertissement si nous installons dans --user et ~/.local/bin n'est pas sur le $PATH

Dans quelle mesure cet avertissement est-il susceptible d'être fragile ? Serait-il converti en chemin absolu? Serait-il insensible à la casse sur les systèmes de fichiers insensibles à la casse ? Traiterait-il et/comme équivalent sous Windows ? Qu'en est-il des liens symboliques ?

Si vous installez un paquet qui n'installe aucun script, l'avertissement n'est de toute façon pas pertinent.

Personnellement, je pense qu'un avertissement fera probablement plus de mal que de bien.

Eh bien, nous pourrions l'implémenter en tant que (équivalent multiplateforme de):

def user_bin_on_path():
    paths = os.environ.get("PATH").split(":")
    for path in paths:
        if os.path.realpath(path) == os.path.realpath(USER_BIN_DIR):
            return True
    return False

Quelque chose comme ça devrait gérer les liens symboliques, les séparateurs de chemin, etc., je pense. Les diables dans les détails et peut-être que nous ne pouvons pas l'obtenir assez précis pour couvrir les différents cas d'angle multiplateformes.

Je suis d'accord que l'avertissement n'est pas pertinent s'il n'y a pas de scripts installés, et je voulais dire que nous ne nous soucierions de l'avertissement que lorsque nous installons des scripts.

L'idée de base est que je ne veux pas que quelqu'un fasse quelque chose comme pip install [--user] foo où le --user est implicite, puis fasse foo et obtienne une "commande introuvable" sans aucune indication sur pourquoi il pourrait ne pas être trouvé. Un avertissement leur indiquera au moins qu'ils doivent ajouter des éléments au PATH. Cela peut également aider les utilisateurs sous Windows à ajouter manuellement leur répertoire utilisateur à leur PATH (ou à exécuter un script pour le faire), ce qui pourrait atténuer le besoin des scripts activate que Steve a soulignés. Bien que je pense que cela signifierait toujours que les valeurs système ont la priorité sur les valeurs utilisateur, cela pourrait encore prêter à confusion puisque l'ordre de PATH et sys.path serait encore inversé.

Oh. J'ai oublié que realpath a canonisé le chemin. Oui, bien sûr, cela fonctionne assez bien.

Ce qui me dérange, c'est que _si_ le test détecte par erreur un problème, l'utilisateur reçoit un avertissement ennuyeux et incorrect sans autre moyen de l'éviter que de modifier son système pour contourner une erreur de la part de pip. Mais étant donné que le test que vous proposez est probablement suffisamment robuste et que nous ne vérifions que si nous installons des scripts, le problème est probablement suffisamment rare pour être ignorable.

Très bien, je pense que nous avons un large accord ici. Je pense que la prochaine étape est d'obtenir un patch. Je vais aller de l'avant et essayer de préparer quelque chose plus tard ce soir ou demain.

Le 10 février 2015, à 12h14, Donald Stufft a écrit :

L'idée de base est que je ne veux pas que quelqu'un fasse quelque chose comme pip install [--user] foo où le --user est implicite, puis fait foo et
obtenir une "commande introuvable" sans aucune indication sur la raison pour laquelle elle pourrait ne pas être
a trouvé.

Debian, et peut-être d'autres Linux, ont en fait un paquet command-not-found
qui invite l'utilisateur à installer un package s'il invoque une commande qui
n'est pas installé.

% paysage d'encre
Le programme 'inkscape' n'est actuellement pas installé. Vous pouvez l'installer en tapant :
sudo apt-get install inkscape

Peut-être pourrions-nous nous y connecter pour prendre en charge les plates-formes.

Le 10 février 2015, à 12h06, Donald Stufft a écrit :

  • Lorsque --global est passé, nous installons toujours dans le site global
  • paquets.

Packages _vendor_ globaux == +1, packages de site globaux == -1.

Vous voulez dire cela dans l'autre sens, n'est-ce pas ?

Je pourrais avoir ma terminologie mélangée, alors je vais être explicite:

/usr/local/lib/pythonX.Y/dist-packages == +1
/usr/lib/pythonX.Y/dist-packages == -1

mais comme vous l'avez dit précédemment, ce n'est pas quelque chose dont pip a vraiment besoin de s'inquiéter
à propos puisqu'il est hérité de distutils et que distutils de Debuntu est patché
faire la bonne chose.

  1. Détecte si les packages de site utilisateur sont désactivés et si c'est le cas, agit comme si
    --global a été passé.

Hmm, je ne suis pas sûr de celui-ci.

Je ne pense pas qu'il y ait un moyen de contourner cela, si les packages de site utilisateur sont désactivés, je
ne pense pas que nous devrions installer là-dedans parce que nous n'avons aucun moyen de savoir
si cette désactivation signifie qu'il n'y a pas de packages de site utilisateur, ou pourquoi. Nous ne pouvons que
supposons qu'il n'y en a pas.

Oh, je vois ce que tu veux dire maintenant. Je suppose que cela a du sens. Mon souci est qu'il
peut être plus difficile de prédire ce que pip va réellement faire, mais comme je
disons, je serais heureux avec un drapeau --dry-run pour que pip puisse _dire_ sans équivoque
vous ce qu'il va faire.

  1. Enfin, si toutes les autres méthodes de détection échouent, agissez comme si --global
    a été réussi.

Pas sûr non plus.

Cela se résume essentiellement à :

Si nous n'avons pas trouvé de raison, nous devrions utiliser --user, comme un drapeau --user, ou
n'ayant pas les permissions d'écrire dans le répertoire, alors ne l'utilisez pas. Ce
est ce qui gardera sudo pip install foo sans un drapeau --global
travaillant. Cela signifie également que c'est la règle la plus importante pour ne pas enfreindre
logiciel fonctionnel qui s'attend à ce que sudo pip install foo agisse de cette façon.

Je vois. Je pense que ça va, car le principal cas anti-utilisation que nous voulons éviter est :

normal_user$ pip installer foo
HÉ VOUS N'AVEZ AUCUNE PERMISSION
normal_user$ sudo pip installer foo
Hé, vous venez d'embrouiller votre système

et la règle "ne pas avoir les permissions d'écrire dans le répertoire implique --user"
s'en occupe.

Oh oui, j'ai oublié la commande introuvable. Pourrait être utile. Au fait, connaissez-vous le bon endroit pour proposer que devubtu ait le bac local de l'utilisateur sur le chemin par défaut ?

Le 10 février 2015, à 16h05, Barry Warsaw [email protected] a écrit :

Le 10 février 2015, à 12h14, Donald Stufft a écrit :

L'idée de base est que je ne veux pas que quelqu'un fasse quelque chose comme pip install [--user] foo où le --user est implicite, puis fait foo et
obtenir une "commande introuvable" sans aucune indication sur la raison pour laquelle elle pourrait ne pas être
a trouvé.

Debian, et peut-être d'autres Linux, ont en fait un paquet command-not-found
qui invite l'utilisateur à installer un package s'il invoque une commande qui
n'est pas installé.

% paysage d'encre
Le programme 'inkscape' n'est actuellement pas installé. Vous pouvez l'installer en tapant :
sudo apt-get install inkscape

Peut-être pourrions-nous nous y connecter pour prendre en charge les plates-formes.


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

Le 10 février 2015, à 13h17, Donald Stufft a écrit :

Oh oui, j'ai oublié la commande introuvable. Pourrait être utile. Au fait est-ce que tu
connaître le bon endroit pour proposer que devubtu ait le bac local de l'utilisateur sur le
chemin par défaut ?

Pas définitivement, mais peut-être les packages adduser ou passwd ? L'ancien possède
/usr/sbin/adduser et ce dernier possède /usr/bin/useradd.

Je ne sais pas si cela aide, mais…

  • ~/.local/bin n'est pas sur le $PATH de beaucoup de gens, y a-t-il quelque chose qui puisse être fait à ce sujet ?

Certains autres projets utilisent /etc/profiled.d/ pour ajouter des répertoires à $PATH. Au moins sur Antergos, je vois ce qui suit (à moins que je ne comprenne mal ce qu'ils font) jre.csh, jre.sh, perlbin.csh, perlbin.sh.

# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
setenv PATH "${PATH}:/usr/lib/jvm/default/bin"
# Do not change this unless you want to completely by-pass Arch Linux' way
# of handling Java versions and vendors. Instead, please use script `archlinux-java`
export PATH=${PATH}:/usr/lib/jvm/default/bin
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && setenv PATH ${PATH}:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && setenv PATH ${PATH}:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && setenv PATH ${PATH}:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && setenv PATH ${PATH}:/usr/bin/core_perl

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2
# Set path to perl scriptdirs if they exist
# https://wiki.archlinux.org/index.php/Perl_Policy#Binaries_and_Scripts
# Added /usr/bin/*_perl dirs for scripts
# Remove /usr/lib/perl5/*_perl/bin in next release

[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin

[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin

[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl

export PATH

# If you have modules in non-standard directories you can add them here.
#export PERLLIB=dir1:dir2

En tant qu'utilisateur pip aléatoire, je veux juste dire _merci_ pour avoir travaillé sur des problèmes d'expérience utilisateur comme celui-ci et comme les autres capturés dans le jalon Améliorer notre expérience utilisateur . Y a-t-il un endroit où je peux contribuer financièrement à cet effort ?

En passant, j'utilise Homebrew et j'ai toujours apprécié le fait que je pouvais juste brew install something et que cela fonctionnerait sans aucun problème avec les autorisations.

Une fois que j'ai compris pourquoi l'installation avec Homebrew ne nécessitait jamais sudo , j'ai essayé de prendre l'habitude de faire pip install --user something , mais ironiquement Homebrew le désactive en raison d'un bogue signalé dans distutils.

Étant donné la popularité d'Homebrew sur OS X, vous voudrez peut-être tous vous pencher sur cette prétendue incompatibilité entre Homebrew et pip install --user .

Quoi qu'il en soit, +1 de ma part pour avoir fait --user la valeur par défaut.

Un suivi rapide. Didier a téléchargé une modification du pip d'Ubuntu en vif qui définit --user par défaut. Je l'ai également autorisé pour la plupart, mais maintenant je pense que c'était une erreur et j'ai l'intention de revenir en arrière pour rusé (mais ne changera probablement pas SRU pour vivid). Voir https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1460203 pour plus de détails et une justification.

+1 pour avoir laissé l'amont piloter le moment de ce changement, car la distinction entre l'utilisateur et le système est déjà suffisamment déroutante sans que les différences de plate-forme n'entrent en jeu.

Cela dit, il peut être raisonnable pour les distributions Linux de commencer à basculer la valeur par défaut sur --user dès que le support --global atterrit dans le pip en amont (pip 8?), Puisque faire des installations globales sur Linux, plutôt que par utilisateur ou per-venv installs, est bien établi comme étant une mauvaise idée avec des effets secondaires potentiellement imprévisibles.

Je l'ai dit à @varsovie en privé, mais je le dirai ici aussi :

Je pense que ce changement est important et je prévois de revenir sur ma pull request pour le terminer. Cependant, je suis une personne étirée sur plusieurs projets et pour le moment, Warehouse est plus important pour moi que ce changement parce que l'héritage PyPI devient de plus en plus lourd à exploiter et je pense que nous devons le remplacer dès que possible. Par conséquent, mon temps sur pip ne se concentre pas sur la réalisation de nombreux changements moi-même, mais plutôt sur le fait de guider les changements apportés par les autres contributeurs ainsi que tout élément du processus de publication.

Cela étant dit, si quelqu'un se soucie vraiment de l'arrivée de cette fonctionnalité le plus tôt possible, il peut reprendre mon travail et le terminer et je serai heureux de l'examiner (et, espérons-le, de le fusionner). Je suis heureux d'en parler avec tous ceux qui veulent le faire et de fournir des conseils sur le changement. Sinon, il faudra attendre que j'aie terminé les éléments les plus urgents pour moi.

Cela vaut peut-être la peine de répéter à ce stade:

Si nous finissons par décider contre 'default to --user', nous devrions envisager les alternatives les moins perturbatrices

  1. Retour à --user (si l'installation échoue en raison d'erreurs de permissions)
  2. (Si l'installation échoue en raison d'erreurs de permissions), encouragez l'utilisateur (en grandes lettres amicales) à essayer --user

FWIW, maintenant que le programme d'installation Windows pour Python 3.5 encourage fortement une installation par utilisateur, je ne suis pas si préoccupé par ce changement qui se produit dans pip. Cela ferait probablement une meilleure option de configuration pour les distributions (avec le remplacement --global ) qu'une nouvelle valeur par défaut ou un repli.

Je voulais juste passer à +1 sur ce problème et dire merci d'avoir travaillé dessus ! Nous organisons actuellement une école d'été scientifique sur Python et avons eu de nombreuses personnes sudo pip install lorsqu'elles ont rencontré des problèmes d'autorisations.

FWIW Je suis en faveur de la valeur par défaut de --user ou de revenir à --user si l'installation échoue en raison d'erreurs d'autorisation. Dans ce cas, je préférerais leur donner les instructions pour inverser ce qu'ils ont fait (par exemple, We installed to your user directory. If you don't want this, then 'pip uninstall my_package' ) plutôt que d'échouer et de leur dire comment réessayer.

Je vois beaucoup de rapports de bogues sur mock en raison de --user - au moins sur Ubuntu où la place de --user sur le chemin est après dist-packages, et donc quel pip installé n'est pas réellement utilisé, pour toute dépendance commune (comme six) qui se trouve dans les dist-packages.

Ils l'ont mis _après_ dist-packages ? C'est une installation cassée IMO.

À droite, les installations utilisateur doivent être placées avant les packages site (/ dist), puis les scripts système et les utilitaires doivent être exécutés avec -I (ou -Es en Python 2).

Oui je suis d'accord :). C'est peut-être corrigé de manière éclatante, mais j'ai certainement entendu des rapports où les choses viennent totalement du mauvais endroit.

Je viens d'utiliser le système pip pour installer setuptools sur ma machine vivid, pour expérimenter.

>>> import setuptools
>>> setuptools.__path__
['/home/robertc/.local/lib/python2.7/site-packages/setuptools']
>>> import sys
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/robertc/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/home/robertc/work/mock']

Donc celui-ci est sain d'esprit. Mais de manière confuse, cela a été introduit de manière vivante - donc IDK. Je verrai si je peux dénicher un reproducteur à un moment donné (à déposer dans le BTS Ubuntu)

Radiomessagerie @varsovie

Les packages de site utilisateur peuvent finir par être réorganisés après les packages de site globaux par les fichiers .pth maléfiques de setuptools. C'était un problème récurrent pour moi jusqu'à ce que j'apprenne à ne jamais utiliser setup.py directement - j'installais quelque chose, et soudain j'utilisais des versions plus anciennes de toutes sortes d'autres choses. Après quelques temps, j'ai écrit un outil agressif pour démêler mon système.

Je pense qu'à tout le moins, pour le moment, pip devrait simplement imprimer un message convivial demandant à l'utilisateur d'exécuter --user si la commande échoue. Bien que le faire passer par défaut ait ses avantages, imprimer un meilleur message ne devrait pas être trop difficile.

C'est une bonne "solution rapide" pour le problème jusqu'à ce que nous passions réellement à la valeur par défaut de --user .

Un --global, --system ou --no-user est également requis si le mode utilisateur est défini dans /etc/pip.conf. Il n'y a pas de moyen facile pour les utilisateurs de remplacer cela pour autant que je sache.

C'est une belle "solution rapide" pour le problème

Mise à jour tardive : #4233 l'a fait.

Les personnes (en particulier les nouveaux arrivants) qui n'utilisent pas Windows devraient vraiment être dirigées vers https://github.com/pyenv/pyenv si elles veulent avoir une bonne expérience. PEP 370 n'a pas beaucoup de sens pour moi aujourd'hui, d'autant plus que ~/.local est XDG_DATA_HOME.

Je pense que je ne serai pas le seul à refuser ce comportement si/quand il se produira. J'espère que la transition se fera en douceur et que je n'aurai pas à modifier le fonctionnement de mon système et à passer des indicateurs CLI supplémentaires, car je suis assez satisfait de pyenv. Bien sûr, je ne sais pas si pyenv fonctionne bien avec Windows, mais le sous-système bash pourrait y aider...

@jcrben pyenv fait pas mal d'hypothèses sur la façon dont les gens utilisent Python (et en particulier sur la façon dont ils acquièrent leurs binaires Python), ce qui signifie que cela fonctionne très bien pour les personnes pour lesquelles ces hypothèses sont valables, mais n'est pas suffisamment universel pour être la recommandation par défaut (il est similaire à conda à cet égard).

La valeur par défaut --user au niveau pip n'aura aucun effet dans les environnements virtuels Python correctement configurés, donc l'impact de ce changement sur les gestionnaires d'environnement tiers comme conda et pyenv sera qu'ils devront s'assurer qu'ils signalent correctement l'état de l'environnement d'une manière que pip et d'autres outils détecteront (c'est-à-dire soit la façon dont virtualenv signale, ou la façon dont le venv de la bibliothèque standard le fait).

Proposition connexe : https://github.com/pypa/pip/issues/1056#issuecomment -218130183.

~A-t-on envisagé de permettre à l'utilisateur de personnaliser le répertoire (probablement via une variable env) pour éviter l'installation directement dans ~/.local ? Je préférerais probablement les imbriquer dans ~/.local/pip ou quelque chose comme ça - en ce qui me concerne, Python n'a aucun droit spécial sur le niveau supérieur de cet espace partagé. ~ Sur 9.0.1, il semble imbriquer des éléments sous ~/.local/lib/python<version> en plus d'ajouter des exécutables à ~/.local/bin , ce qui, je suppose, est bien ...

@jcrben Aye, l'emplacement cible est en fait le répertoire du site utilisateur de Python, qui reflète le schéma de dénomination du répertoire système site-packages : https://docs.python.org/3/library/site.html#site.USER_SITE

C'est déjà configurable au niveau de l'interpréteur au moyen de la variable d'environnement PYTHONUSERBASE : https://docs.python.org/3/using/cmdline.html#envvar -PYTHONUSERBASE

Pour les personnes intéressées, je viens de publier https://github.com/ofek/hatch qui contient les commandes de package install , uninstall et update qui ont ce comportement par défaut. Pour modifier le système, les utilisateurs peuvent utiliser l'option -g/--global similaire à https://github.com/npm/npm.

Compte tenu du récent problème avec les packages infectés par des logiciels malveillants sur PyPI , je pense qu'il est dans l'intérêt de pip de faire ce qu'il peut pour décourager l'utilisation de sudo pip install ... , en particulier en tenant compte du fait que les scripts d'installation peuvent exécuter du code arbitraire lors de l'installation. L'installation de packages infectés en tant qu'utilisateur est déjà assez mauvaise, mais c'est bien pire s'ils sont installés en tant que root.

L'installation par défaut des utilisateurs signifie que moins de personnes ajouteront sudo à leur commande pip, ce qui signifie que les logiciels malveillants installés accidentellement peuvent faire moins.

Comme prochaine étape concrète, j'ai signalé un problème distinct pour l'ajout d'un indicateur --global : https://github.com/pypa/pip/issues/4865

C'est presque certainement une mauvaise idée dans les environnements virtualenv ou conda. Tout ce qui est installé dans .local lorsqu'un environnement est actif peut facilement casser un autre environnement. Alors, quelle est la pensée dans ces cas?

cc @msarahan @kalefranz

Ce problème ne s'applique pas à l'intérieur d'un environnement virtuel actif - il s'applique uniquement lorsqu'aucun environnement actif n'est détecté et qu'aucune des options de définition de cible ( --prefix , --root , etc.) n'a été donnée sur la ligne de commande.

Comment cela est-il déterminé ?

Nous avons envisagé de désactiver par défaut ~/.local sur sys.path pour python dans les environnements conda, qui par définition se trouve être n'importe quel python installé par conda. C'est délicat cependant. Dans tous les cas, nous pourrions finir par violer les attentes d'un groupe d'utilisateurs. Discussion sur https://github.com/conda/conda/issues/7173

Pip n'a-t-il pas pu charger un argument à partir de variables d'environnement commençant par PIP_ ? Cela fonctionne-t-il pour --user ? Quel serait le nom complet de la variable ?

Ce serait PIP_USER .

Documents : https://pip.pypa.io/en/stable/user_guide/#environment -variables

PIP_USER=yes pour être exact, merci ! L'utilisation de variables d'environnement est beaucoup plus facile pour l'utilisation de CI car vous n'avez qu'à les définir une seule fois et elles seront utilisées chaque fois que les commandes seront appelées.

J'ai dû faire une logique vraiment moche pour travis où apparemment certaines étapes sont exécutées en tant qu'utilisateur normal sans virtualemv et certaines à l'intérieur d'un virtualenv, et vous n'avez aucune idée de laquelle ce serait.

à l'intérieur de virtualenv, il est probable que -user échouera si vous n'utilisez pas de packages de site (ce qui cause d'autres problèmes).

Ce ment que j'avais pour détecter virtualenv dans bash et éviter d'ajouter le -user ou l'exécution échouera.

C'est moche et m'a fait perdre beaucoup de temps à déboguer, je suis sûr que d'autres feront face à la même chose.

Je pense que nous avons besoin d'une option qui active une solution de secours concernant l'installation : comme l'installer sur l'utilisateur si vous le pouvez et revenir au système.

pip ne devrait échouer que s'il ne parvient pas à trouver un emplacement pour installer un paquet.

Tout mouvement à ce sujet?

Je ne l'ai pas vu mentionné, mais peut-être que pip devrait se plaindre si --user est passé lorsqu'il est exécuté sous sudo.

Ces problèmes non résolus éloignent les programmeurs de pip et même de python et les obligent à utiliser d'autres packages ou même d'autres langages de programmation comme javascript et npm avec moins de problèmes comme celui-ci. Pour un débutant qui veut utiliser python, ces options supplémentaires nécessaires sont frustrantes.

Pourquoi --user serait-il la valeur par défaut ? Ne peut-il pas être spécifié explicitement? Je ne peux pas exécuter pip --target à cause de cela, il se plaint qu'il ne peut pas être utilisé conjointement avec l'utilisateur. Une idée de comment l'éviter ?

@dmikov : ce n'est pas la valeur par défaut. À moins que vous n'utilisiez la version cassée de Debian/Ubuntu, auquel cas vous pouvez contourner --user automatiquement défini en utilisant : PIP_USER=0 pip install -t ... . Ou mieux encore, installez une version officielle et utilisez-la.

J'ai rêvé la nuit que l'option --user devienne la valeur par défaut (je ne plaisante pas), y a-t-il une chance que mes rêves se réalisent bientôt ?

J'ai besoin d'aide pour installer pygame, il n'arrête pas de dire une syntaxe invalide

j'ai utilisé
python3 -m pip install -U pygame --user
est-ce mal que dois-je faire?

@flamedro56 : au lieu de commenter un problème au hasard, veuillez en ouvrir un nouveau et fournir plus d'informations : version de Python, version de pip, système d'exploitation, sortie de la commande...

Programme d'installation reCAPTCHA

Que diriez-vous d'avoir une nouvelle option de configuration default=system,user ? Ce serait suffisamment explicite pour que personne ne pense que cela signifie "toujours utilisateur, même dans virtualenv". Cela permettrait une voie de migration gracieuse.

Voir #4575.

On dirait que Manjaro essaie de définir --user par défaut.

Y a-t-il du nouveau en amont sur ce problème ?

@Tids : "filesystem-2018.9-3 ajoute $HOME/.local/bin à votre $PATH par défaut." est la pièce supplémentaire clé que Manjaro fait bien.

Debian combine "default to --user" au niveau Python avec "$HOME/.local/bin n'est pas sur votre $PATH par défaut" au niveau du compte utilisateur, et c'est le combo qui casse les choses.

Dans # 7002, j'ai essayé de faire en sorte que pip effectue une installation utilisateur par défaut lorsque le répertoire global des packages de site n'est pas accessible en écriture et que les packages de site utilisateur sont activés. Cela devrait en grande partie éviter de faire une installation utilisateur lorsque vous vouliez installer dans un env, tant que vous avez la permission de modifier l'env.

Je cherche d'abord à discuter de l'idée - ne nous enlisons pas dans l'examen de la mise en œuvre avant d'avoir réfléchi à la pertinence de faire cette chose.

Il convient de noter que le mélange d'installations d'utilisateurs et d'installations de non-utilisateurs (de pip lui-même) pose de nombreux problèmes - voir # 7209 comme exemple récemment.

Bien que n'étant pas directement lié à ce problème (et en effet, si nous utilisons par défaut l'utilisateur, cela peut atténuer quelque peu la situation), cela souligne la nécessité d'une réflexion approfondie sur la manière dont nous gérons toute transition vers --user par défaut.

(J'ajoute principalement ce commentaire ici pour qu'il soit enregistré quelque part - ce n'est généralement pas du tout un problème de pip, mais plutôt une complication du fonctionnement général du répertoire USER_SITE de Python, qui n'est pas suffisamment bien compris par les utilisateurs installant avec --user ).

Il semble que le problème soit que PATH (pour trouver des commandes) et sys.path (pour trouver des importations Python) ont des priorités opposées, donc le script de lancement d'une installation essaie de charger le paquet depuis le autre. Ce n'est probablement pas spécifique à pip - cela pourrait affecter n'importe quel paquet qui installe un script.

Je ne sais pas trop ce que nous pouvons faire à ce sujet, mais je suis d'accord que cela vaut la peine d'y réfléchir.

Oui, c'est la principale "complication de USER_SITE" que j'avais en tête. IMO, dépréciant les scripts wrapper et ne prenant en charge que python -m pip est la solution la plus efficace. (Je ne suis pas contre les wrappers en soi, mais les problèmes que nous rencontrons avec eux sont généralement des personnes qui exécutent accidentellement le mauvais wrapper, donc la résolution des problèmes de script de wrapper n'est généralement pas un problème de pip en tant que tel, plutôt un "diagnostic et correction d'une mauvaise configuration de l'environnement utilisateur " publier)

Vous voulez dire déprécier le script wrapper pip , ou déprécier les scripts wrapper comme une chose que pip peut installer ?

Je suis certainement -1 sur ce dernier - la possibilité d'installer des commandes est très utile, même si cela pose des problèmes.

Déprécier pip en faveur de python -m pip pourrait être plus raisonnable. Au fur et à mesure que pip s'installe dans l'environnement Python dans lequel il s'exécute, il est logique de savoir clairement lequel. Mais ce serait quand même une perte de confort, et une grosse rupture avec ce à quoi les gens sont habitués.

Je voulais dire spécifiquement les scripts wrapper pour pip lui-même. D'accord, c'est une perte de commodité, et je ne serais pas contre leur conservation sous une forme ou une autre (#3164 suggère d'avoir un nouveau pip-cli qui ne fournit que les emballages) mais le point clé serait pour python -m pip comme moyen pris en charge pour exécuter pip.

Impossible d'appeler le script pip wrapper pour afficher un avertissement si le python actuel (dans le PATH ou tout ce qui serait utilisé avec python -m pip ) n'est pas le python utilisé par pip ? Peut-être même déléguer à python -m pip s'il est appelé de cette façon ?

De même, pipenv avertit si l'utilisateur est déjà dans un virtualenv, et si c'est le cas utilise ce virtualenv au lieu de gérer le sien, après avoir émis un avertissement.

D'accord, en notant ici que # 7002 a été approuvé par 3 des 6 mainteneurs de pip à ce stade.

Il fait basculer pip des installations non-utilisateur aux installations utilisateur par défaut, dans la plupart des cas où nous devrions vraiment faire des installations utilisateur de toute façon. J'ai deux préoccupations plus larges concernant cette modification, que nous devrions comprendre avant de publier la version qui apporte cette amélioration.

  • Voulons-nous un mécanisme pour désactiver explicitement les installations des utilisateurs une fois que nous y passons par défaut ? Si oui, en quoi serait-il différent de --no-user ? (Je suis d'accord pour renommer --no-user en --global en tant qu'opt-out explicite).
  • Quelle est notre stratégie de "transition" ?

    • Comment voulons-nous communiquer ce changement ?

    • dire aux utilisateurs d'être prudents lors de cette mise à jour ?

    • Quels types de problèmes attendons-nous des utilisateurs lors de la mise en œuvre et de la publication de ce changement ?

Je dirais que --global est mal nommé si vous êtes dans un environnement. Pour flit install , l'opposé de --user est --env , ce que je voulais vaguement inclure "l'environnement système Python", mais je ne pense pas que ce soit totalement clair non plus. Peut-être que --no-user est toujours le meilleur choix - c'est clairement le contraire de --user .

Je pense que --no-user (ou la variable d'environnement ou l'entrée de configuration équivalente) devrait vous permettre de retrouver le comportement existant, car la valeur par défaut à l'heure actuelle est effectivement user = False .

Le seul scénario que j'ai trouvé où le changement serait déroutant est si vous pensez avoir l'autorisation d'installer dans un environnement (avec le site utilisateur activé, par exemple conda) alors qu'en réalité vous ne l'avez pas : un échec est plus clair que de faire un l'installation de l'utilisateur, même s'il y a un message de journal à ce sujet. Je n'ai pas pensé à un bon moyen d'améliorer cela.

Il est également possible que la détection de l'inscriptibilité tourne mal. Un faux positif vous donne simplement le comportement existant (essayez et échouez à faire une installation normale). Un faux négatif ferait l'installation d'un utilisateur alors qu'il aurait pu en faire une normale.

Il fait passer le pip des installations non-utilisateur aux installations utilisateur par défaut.

Pas (par exemple) sous Windows, où (par défaut) l'installation de Python est une installation par utilisateur et les packages de site sont inscriptibles par défaut. C'est quelque chose que je préfère en général à propos de # 7002, car mon expérience depuis l'ouverture de ce numéro (# 1668) est qu'il est trop facile de se retrouver dans un pétrin avec des environnements "mixtes" où vous avez des packages comme pip installés à la fois dans des packages de site et site utilisateur. Je suis donc maintenant en faveur de faire des installations système si possible, et de ne faire des installations utilisateur que dans des cas comme les Pythons gérés par le système Linux, où les packages de site ne peuvent pas être écrits.

Ayant dit cela:

  1. Il semble inutile d'utiliser une option --no-user , car # 7002 signifie que vous n'obtenez une installation utilisateur que si une installation système échoue de toute façon.
  2. Je pense que la chose la plus importante que nous devons communiquer concernant la transition est que les gens doivent faire très attention aux installations multiples, et c'est quelque chose qui ne peut être traité que par la compréhension et l'éducation de l'utilisateur, et non par une solution de contournement dans pip. C'est fondamentalement un problème Python de base. Nous pourrions étendre pip check pour signaler quand il y a un site et qu'un utilisateur installe un paquet et que l'utilisateur observe celui du site, je suppose...

Il semble inutile d'utiliser une option --no-user

Pour être clair, cela existe déjà, même si ce n'est probablement pas souvent utile. Si vous avez user=true dans un fichier de configuration, --no-user devrait remplacer cela.

Pour être clair, cela existe déjà

Désolé, j'aurais dû être plus clair. Je ne vois aucun intérêt à avoir "un mécanisme pour désactiver explicitement les installations de l'utilisateur une fois que nous y passons par défaut", du moins dans le sens où je suppose que @pradyunsg voulait dire, qui consiste à désactiver le comportement # 7002, qui n'est pas la même chose que "passer aux installations utilisateur par défaut", comme je l'ai dit.

En fait, je ne suis pas sûr que ce soit plus clair ;-) Peut-être que tout ce que je veux dire, c'est "nous n'avons pas besoin de plus d'options que celles que nous avons actuellement"...

Hmm ... @pfmoore Après # 7002, que faut-il pour appeler ce problème résolu?

PS: J'avais écrit ce commentaire plus tôt à la hâte et il a été posté par accident. Les balles sont OK ; J'étais encore en train de rédiger le paragraphe précédent, quand il a été posté. Désolé pour toute confusion qui aurait pu causer.

@pradyunsg Étant donné que je suis maintenant beaucoup moins enclin à penser que --user par défaut est une bonne idée à moins que ce ne soit absolument nécessaire (les cas # 7002 adresses), je dirais plutôt que nous pouvons abandonner ce problème comme n'est plus une bonne idée maintenant que #7002 est terminé.

En prenant vos 2 puces comme des choses dont nous pourrions avoir besoin pour compter # 7002 comme complet, mes commentaires ci-dessus couvrent cela.

J'ai suivi les notes de version ici.
https://pip.pypa.io/en/stable/news/#id3
"Par défaut, une installation utilisateur est effectuée (comme si --user était passé) lorsque le répertoire principal des packages du site n'est pas accessible en écriture et que les packages du site utilisateur sont activés. (#1668)"

Mes builds échouent maintenant avec

ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Cela semble résolu en supprimant le --user de mes commandes pip.

Était-ce un comportement attendu ? Les notes de version ne semblent pas refléter cela.

lien vers le script qui échoue maintenant sur pip 20.0.1 (la suppression du --user corrige l'échec dur)
https://github.com/lfit/releng-global-jjb/blob/master/shell/python-tools-install.sh

S'il est exact que les packages de site utilisateur ne peuvent pas être importés à partir de cet environnement, c'est le comportement attendu, mais il est orthogonal à ce PR. Ce contrôle a été introduit il y a des années (# 567), mais il semble qu'il ait été cassé avec venv jusqu'à récemment (# 7155). Il y a une note de version pour ça :

Gérer correctement les site-packages du système, dans les environnements virtuels créés avec venv (PEP 405).

Ah oui, merci pour vos commentaires. J'ai compris ça...
mon script remplissait .local/bin/
quand j'ai couru

python3 -m venv ~/.local

puis dans un shell de connexion ubuntu (#!/bin/bash -l) .local/bin est ajouté au chemin (donc appeler python3 appelle maintenant l'exécutable .local/bin/python3) Ce que nous ne voulons pas.
Je n'ai jamais eu besoin d'exécuter python3 -m venv ~/.local
ou appelez mes scripts à partir d'un shell de connexion, et la suppression des deux ou de l'un de ces problèmes le résout.

#fresh ubuntu docker
root<strong i="13">@7d8107816f64</strong>:/# python3 -m pip install  --user --upgrade pip
Successfully installed pip-20.0.1
root<strong i="14">@7d8107816f64</strong>:/# python3 -m pip --version
pip 20.0.1 from /root/.local/lib/python3.6/site-packages/pip (python 3.6)
root<strong i="15">@7d8107816f64</strong>:/# ls root/.local/bin/pip
pip     pip3    pip3.6
#Now we populate ~/.local/bin/
root<strong i="16">@7d8107816f64</strong>:/# python3 -m venv ~/.local
root<strong i="17">@7d8107816f64</strong>:/# ls root/.local/bin/
activate          activate.fish     easy_install-3.6  pip3              python
activate.csh      easy_install      pip               pip3.6            python3
root<strong i="18">@7d8107816f64</strong>:/# ./root/.local/bin/python --version
Python 3.6.9
root<strong i="19">@7d8107816f64</strong>:/# ./root/.local/bin/python -m pip install  --user --upgrade pip
ERROR: Can not perform a '--user' install. User site-packages are not visible in this virtualenv.

Donc, si jamais nous exécutons l'exécutable .local/bin/python, nous ne pouvons pas installer pip avec --user

Oh, j'avais manqué que tu fasses python3 -m venv ~/.local . Cela risque de confondre des outils comme pip, car ~/.local est le préfixe pour les installations --user (sous Linux). venvs et --user sont deux manières _différentes_ d'installer des paquets sans apporter de modifications à l'ensemble du système : vous devez utiliser l'une ou l'autre. La création d'un venv dans ~/.local crée un étrange hybride des deux.

Le nouveau comportement est probablement pratique pour beaucoup, mais les installations "utilisateurs" m'ont causé du chagrin en tant que développeur Web - j'ai souvent besoin de préparer des virtualenvs qui seront déployés sur nos machines de production, et si un paquet est installé dans ma bibliothèque utilisateur, alors par défaut pip refusera de l'installer sur le virtualenv que je prépare, et se terminera toujours avec succès . La notification indiquant qu'il a décidé de ne pas installer le package est enterrée dans 30 ou 40 pages de sortie du script que j'utilise pour préparer le virtualenv. L'effet final est qu'une fois que le virtualenv est déployé, les packages de mon répertoire personnel ne sont plus disponibles, donc certains packages aléatoires manquent dans mon application Web de production, et il tombe mort.

Je suis prêt à admettre que mon cas d'utilisation n'est pas typique, alors c'était peut-être encore une bonne idée d'un point de vue général de l'utilisabilité.

Pour ceux qui ont eu des problèmes similaires, il y a plusieurs façons de le contourner :

  • Ajoutez --force-reinstall à toutes vos lignes de commande pip install dans les scripts, etc.
  • Supprimez ~/.local/lib/python* et modifiez ~/.pip/pip.conf pour ajouter user = no dans la section global :
[global]
user = no
  • Faites quelque chose de plus drastique, comme changer ~/.local/lib dans un fichier plutôt qu'un répertoire :smirk:

Comme toujours, chers mainteneurs d'emballages, merci pour tout ce que vous faites - je suis sûr qu'il est pratiquement impossible de changer quoi que ce soit sans casser les affaires de quelqu'un, et le fait que vous forgiez quand même est en fait génial, car cela nous permet de progresser.

Ah, les installations d'utilisateurs peuvent également causer d'énormes problèmes dans les environnements d'intégration continue, où de nombreuses choses différentes sont exécutées sous le même compte d'utilisateur, mais les gens s'attendent toujours à ce que les versions soient isolées les unes des autres. Nous avons résolu ce problème en rendant ~/.local en lecture seule, mais les solutions ci-dessus fonctionneraient probablement aussi.

Lorsque vous créez un virtualenv avec les options par défaut, il est isolé : il ne peut pas voir vos packages de site utilisateur ou système, et par conséquent pip ne devrait fonctionner qu'avec les packages installés dans l'env. C'est devenu la valeur par défaut il y a de nombreuses années, à cause exactement du genre de problèmes que vous décrivez.

Si vous créez virtualenvs avec l'option --system-site-packages (ou de très anciennes versions de virtualenv où c'était la valeur par défaut), ils agissent comme une superposition sur les packages que vous auriez autrement installés, à la fois à l'échelle du système et dans votre maison annuaire. Si vous souhaitez que les packages système soient visibles mais pas les packages utilisateur, vous pouvez exécuter Python avec l' option -s ou la variable d'environnement PYTHONNOUSERSITE .

Oh! Je suis vraiment désolé, tu as tout à fait raison. L'étrange politique système-site-packages de mon organisation frappe à nouveau. Merci d'avoir signalé quelques solutions.

Aucun problème. Les packages de site système étaient plus courants il y a quelques années, lorsque nous comptions souvent sur les gestionnaires de packages système pour des choses comme numpy, alors peut-être vaut-il la peine de revoir cette politique. Mais il peut encore y avoir des raisons sensées de l'utiliser aujourd'hui.

Fermeture conformément à https://github.com/pypa/pip/issues/1668#issuecomment -544569965.

Merci beaucoup @takluyver ! ^>^

@takluyver Merci d'avoir résolu le problème qui me préoccupe depuis longtemps
Mais j'ai remarqué que lors de l'installation de packages avec des utilisateurs non privilégiés, Windows 10 python 3.8.2 avec pip 20.0.2 échoue toujours.

ERROR: Exception:
Traceback (most recent call last):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\cli\base_command.py", line 186, in _main
    status = self.run(options, args)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 253, in run
    options.use_user_site = decide_user_install(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 604, in decide_user_install
    if site_packages_writable(root=root_path, isolated=isolated_mode):
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 548, in site_packages_writable
    return all(
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\commands\install.py", line 549, in <genexpr>
    test_writable_dir(d) for d in set(get_lib_location_guesses(**kwargs))
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 140, in test_writable_dir
    return _test_writable_dir_win(path)
  File "c:\program files (x86)\python38-32\lib\site-packages\pip\_internal\utils\filesystem.py", line 153, in _test_writable_dir_win
    fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL)
PermissionError: [Errno 13] Permission denied: 'c:\\program files (x86)\\python38-32\\Lib\\site-packages\\accesstest_deleteme_fishfingers_custard_m59lch'

Je pensais que cela pouvait être dû au fait que OSError errno était errno.EACCES mais errno.EPERM .

@catPill veuillez ouvrir un nouveau problème afin que cela puisse être suivi correctement. Il est parfaitement plausible que j'ai raté quelque chose sur Windows.

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