Pip: Standardmäßig --user

Erstellt am 21. März 2014  ·  170Kommentare  ·  Quelle: pypa/pip

Wenn pip auf einem System installiert wird, auf dem ein Betriebssystem mit Python installiert ist, gibt es derzeit ein Problem, bei dem pip install foo einen Fehler ausgibt, weil es keine Dateiberechtigungen hat. Dies führt dazu, dass Benutzer stattdessen sudo pip install foo ausführen, das global auf dem System Python installiert wird. Dies führt zu einem Problem, bei dem Benutzer pip verwenden, um Pakete auf Systemebene zu verwalten, wenn sie wahrscheinlich den Systempaket-Manager verwenden sollten.

Meine Absicht ist also, dass pip standardmäßig --user sein sollte, aber es gibt ein paar Knackpunkte dabei:

  • Wie interagiert dies mit Windows? Macht das dort Sinn?
  • Wie interagiert dies mit altinstallierten Pythons? Speziell solche, die mit Tools wie https://github.com/yyuu/pyenv installiert werden
  • Was tun wir, wenn Leute Pip als Root aufrufen? Die Installation in /root/.local/ erscheint nicht sehr sinnvoll.
  • Was bedeutet das für get-pip und die pypa-Installationsanweisungen ?
  • ~/.local/bin ist nicht im $PATH vieler Leute, kann man dagegen etwas tun?
  • --user -Installationen haben keinen Vorrang vor globalen easy_install -Paketen, was ziemlich unerwartet sein kann.

Es gibt eine Reihe von Problemen, die hier relevant sind: #624 #1443 #1153 #1500 #1051

/cc @ncoghlan

user scheme auto-locked enhancement

Hilfreichster Kommentar

Ich habe nachts davon geträumt, dass die --user -Option zur Standardeinstellung wird (kein Scherz), gibt es eine Chance, dass meine Träume bald wahr werden?

Alle 170 Kommentare

Was bedeutet das für die pypa-Installationsanweisungen?

Derzeit befindet sich die Erwähnung des Root- oder Administratorzugriffs in einer Fußnote, sodass die Anweisungen im Wesentlichen gleich bleiben würden (vorausgesetzt, get-pip wird automatisch auch auf --user gesetzt). Die Änderung würde darin bestehen, zu erklären, dass sie am Ende Installationen erhalten, die nur für ihren aktuellen Benutzer gelten.

Unabhängig von der Änderung von --user müssen die aktuellen Anweisungen erklären, dass einige Distributionen wie Debian das Sicherepip deaktivieren, also sollten sie nicht danach suchen, um Pip zu bekommen.

Langfristig bin ich mir ziemlich sicher, dass sie es aktiviert lassen werden, sie finden nur heraus, wie es geht.

Obwohl dieses Problem so beschrieben wird, dass es darum geht, wo pip Pakete standardmäßig verwalten soll, ist es fast noch wichtiger (zumindest für mich), dass es indirekt darum geht, wo get-pip pip standardmäßig platzieren wird.

Wie interagiert dies mit altinstallierten Pythons?
Speziell solche, die mit Tools wie https://github.com/yyuu/pyenv installiert werden

Das Benutzerschema ist .local/lib/pythonX.Y/site-packages . Wenn Sie also mehrere Pythons mit derselben Haupt-/Nebenversion verwalten, könnten Sie am Ende ein Durcheinander haben, denke ich.

Für solche Tools, die echte Pythons verwalten, wäre das Anheften von pip an den globalen Modus sinnvoll.

Ein relevantes Problem im Redhat/Fedora-Bugtracker https://bugzilla.redhat.com/show_bug.cgi?id=662034#c10

Es sieht so aus, als ob PATH=$PATH:$HOME/.local/bin:$HOME/bin für Fedora/RedHat bereits in ihrem /etc/skel/.bash_profile ist. Dies würde dazu führen, dass Dinge, die mit --user installiert wurden, immer noch standardmäßig angezeigt werden, zumindest für Bash-Benutzer (Standard-Shell). Vielleicht haben andere Distributionen das schon?

Soweit ich weiß, gibt es bei Windows keine besonderen Unterschiede. Aber wir haben gerade erst das Standard-Python-Verzeichnis in den PATH der Leute gebracht, ich erwarte nicht, dass es besonders einfach sein wird, ein Verzeichnis für Skripte pro Benutzer zu bekommen - und es kann auch technische Schwierigkeiten geben, da bin ich mir nicht sicher Das Einfügen einer Umgebungsvariable auf Benutzerebene wie %LOCALAPPDATA% in die Systemebene %PATH% funktioniert sogar :-(

Ich bin dagegen, das zu überstürzen. Ich würde lieber warten, bis wir mehr Erfahrung mit Benutzerinstallationen haben und es geschafft haben, die Probleme zuerst auszubügeln. Ich weiß, das ist ein Henne-Ei-Problem, aber ich sehe es nicht als hilfreich an, in eine Veränderung zu eilen.

Außerdem muss ich mit meinem Windows-Hut sagen, dass es keine so gute Rechtfertigung ist, es Unix-Benutzern, die noch nicht herausgefunden haben, dass die nachlässige Verwendung von sudo schlecht ist, dumme Dinge zu tun, schwerer zu machen. .

Ich gehe davon aus, dass dies nur zutrifft, wenn Pip von einem System-Python ausgeführt wird.

Nun, der Unterschied zu Windows ist, dass es kein vom System bereitgestelltes Python gibt, wie es auf * nix der Fall ist, das auch vom System bereitgestellte Python-Pakete enthält :)

Ich will das auch nicht besonders überstürzen. Ich wollte nur die Diskussion anstoßen.

Dies betrifft nicht wirklich Leute, die sudo pip install eingeben, da ich denke, dass die Installation von etwas als root immer noch standardmäßig zu den System-Site-Paketen gehen sollte. Dies würde die Leute dazu bringen, --user zu verwenden, wenn sie als nicht privilegierter Benutzer ausgeführt werden. Im Moment erhalten Sie, dass pip install als normaler Benutzer nur mit einem Berechtigungsfehler bombardiert wird. Selbst wenn wir diese Botschaft verbessern und --user vorschlagen, ist das immer noch nicht die beste UX.

Im Gespräch mit einem der Fedora-Leute denke ich, dass die Möglichkeit, dies zu tun, darin besteht, eine Berechtigungsprüfung zu implementieren. Wenn ich die Berechtigung habe, in das Verzeichnis site-packages zu schreiben, bin ich ein privilegierter Benutzer und pip installiert in das globale Python. Wenn nicht, bin ich ein nicht privilegierter Benutzer und es wird in --user installiert.

In Bezug auf Windows umgehen wir das Problem normalerweise, weil wir Python standardmäßig in einem nicht privilegierten Verzeichnis installieren, sodass pip bei der globalen Installation keine UAC auslöst. Wenn jemand dies ändert, um stattdessen in Programmdateien zu installieren, wird UAC ausgelöst, wenn er pip ausführt (was auch in Ordnung ist). Ich bin mir nicht sicher, was passiert, wenn sie im Installationsprogramm eine Installation pro Benutzer auswählen.

Wie Paul anmerkt, enthält PATH unter Windows noch nicht das Verzeichnis _user_ scripts (nur das globale), also lohnt es sich auf jeden Fall, dies zu berücksichtigen.

Ich sehe jedoch keine größeren Hindernisse auf der POSIX-Seite. Wie klingt diese UX-Idee: Überprüfen Sie für Wheel-basierte Installationen, ob Berechtigungen für das Installationszielverzeichnis vorhanden sind, und wenn der Benutzer keine Schreibberechtigungen hat, geben Sie eine Eingabeaufforderung ein, in der Sie gefragt werden, ob er stattdessen eine --user-Installation durchführen möchte? Ein neues „--global“- oder „--system“-Flag würde die „Nein“-Antwort erzwingen.

Und dann könnten wir irgendwann in der Zukunft die Eingabeaufforderung überspringen und einfach --user annehmen, wenn die Berechtigungen für eine globale Installation nicht richtig wären.

Eine Eingabeaufforderung (außer bei --no-input) ist wahrscheinlich für den Übergangsschritt sinnvoll. Ich denke, das Überprüfen von Berechtigungen sollte auch für Windows funktionieren, da sich der Speicherort standardmäßig an einer Stelle befindet, an der die Benutzer Berechtigungen haben, und das einzige Mal, dass sie darauf stoßen würden, wäre, wenn sie einen Systemadministrator verwenden, der Python zur Verfügung stellt, der dies ausdrücklich getan hat. t ihnen die Erlaubnis geben.

Im Wesentlichen macht dies unseren Fehlermodus viel besser.

Dies macht es für Unix-Benutzer schwieriger, die diesen sorglosen Umgang mit sudo noch nicht herausgefunden haben
Es ist schlecht, dumme Sachen zu machen, ist nicht wirklich eine gute Rechtfertigung..

sudo und Sicherheit ist meiner Meinung nach wirklich ein zweitrangiges Thema.
Hier geht es in erster Linie darum, den Konflikt zwischen Betriebssystempaketierung und Pip im System Python zu verhindern.
Derzeit werden Linux-Benutzer oft in eine unmögliche Situation gebracht.

  1. Betriebssystemmandat: „Verwenden Sie das Betriebssystempaket mgr; Infizieren Sie Ihr System nicht mit von Roque Pip installierten Paketen (einschließlich eines get-pip 'd pip)'
  2. Realität: „Die Betriebssystempakete (einschließlich Pip) sind zu alt, und ich kann nicht auf die experimentelle Version der Distribution aktualisieren, nur um Upgrades für einige Pakete zu erhalten. Ich werde abtrünnig …“

Ein weiterer kleiner Schritt besteht darin, zu dokumentieren (vorausgesetzt, wir testen es), dass Sie get-pip.py --user können, und den PUG --user als Möglichkeit für die Installation von virtualenv (und wheel und twine auch, wenn nicht in einer virtuellen Umgebung)

FWIW, Distributionsanbieter betrachten den Status quo ebenfalls als Problem und suchen nach verschiedenen Möglichkeiten, die Tools für selektive Upgrades zu verbessern, ohne die Kernkomponenten des Betriebssystems zu beeinträchtigen. Es lohnt sich jedoch immer noch, von der Upstream-Seite aus anzugehen, da sich diese Bemühungen in verschiedenen Stadien der Reife befinden und wir eine konsistente plattformübergreifende Lösung für Endbenutzer wünschen.

Ich habe kein Problem damit, Dinge zu ändern, um die Zusammenarbeit mit Distributionen unter Unix zu unterstützen; Wenn es unter Unix und nicht unter Windows akzeptabel ist, standardmäßig --user zu verwenden, ist das für mich in Ordnung. Ich sehe den Wechsel von einer schlechten Erfahrung unter Unix zu einer schlechten Erfahrung unter Windows einfach nicht als guten Kompromiss an. Und ich bin noch nicht davon überzeugt, dass --user unter Windows für die Hauptsendezeit bereit ist.

Beachten Sie, dass das Auslösen von UAC beim Ausführen von pip unter Windows schlecht ist, da es eigentlich bedeutet, dass pip nur in einem Konsolenfenster mit erhöhten Rechten ausgeführt wird. Es bedeutet nicht, dass Pip-Benutzer eine nette Eingabeaufforderung erhalten, zu der sie "OK" sagen können, leider funktionieren GUI-Apps nur so ...

@pfmoore Was sollte Ihrer Meinung nach die Benutzererfahrung von Windows sein, wenn Sie pip install etwas tun und keine Berechtigungen zum Schreiben in das Verzeichnis haben?

FWIW Ich bin völlig einverstanden damit, dies optional zu machen, abhängig von Windows oder nicht. Ich frage mich nur, ob die Überprüfung von "Habe ich Berechtigungen zum Schreiben in den Ordner "site-packages"" dies in 99% der Installationen sowieso nicht erreicht, und ob die Installation unter --user eine bessere Erfahrung in der wäre Bruchteil der Fälle, in denen Sie keine Schreibberechtigungen für das Verzeichnis site-packages haben.

Mit anderen Worten, wenn wir die Berechtigungen überprüfen, ersetzt der Vorschlag nicht die globale Installation durch eine Benutzerinstallation, sondern einen Berechtigungsfehler durch eine --user -Installation.

Der Vorschlag ersetzt die globale Installation nicht durch eine Benutzerinstallation
es ersetzt einen Berechtigungsfehler durch eine --user install

ok, aber denken Sie daran, dass die Berechtigungsprüfung (#1048) nicht die einfachste Sache sein wird

Im Wheel-Fall wird es ziemlich einfach sein, und wir können den 99,9% -Fall mit sdists abdecken, es sollte nur ein Problem in setup.py geben, das wirklich abgefahrene Dinge tut.

Was sollte Ihrer Meinung nach die Benutzererfahrung von Windows sein, wenn Sie etwas per Pip installieren und keine Berechtigungen zum Schreiben in das Verzeichnis haben?

Nun, das Schreiben in das Verzeichnis site-packages ist unter Windows so selten, dass ich mir nicht sicher bin, wie relevant die Frage in der Praxis ist. Aber wenn es passiert, würde ich sagen, dass ein Fehler mit der Aufschrift "System Site-Packages ist nicht beschreibbar - wollten Sie --user verwenden?" wäre der sinnvolle Ansatz.

Eigentlich denke ich, dass das auch unter Unix besser wäre. Das Umschalten des Verhaltens in Abhängigkeit von der Beschreibbarkeit ist bizarr, und es ist mir nicht klar, ob die Verwendung --user für ein persönlich erstelltes Python in einem beschreibbaren Verzeichnis der richtige Ansatz ist (aber ich habe genau null Erfahrung mit einem solchen Setup, also Ich habe nichts, um diese Meinung zu untermauern).

Vorschlag: Beginnen Sie mit einem Fehler, der --user wie oben vorschlägt. Sobald die Leute --user häufiger verwenden und wir mehr Erfahrung damit haben, sollten wir uns überlegen, die Standardeinstellung zu ändern.

Der Ansatz, den Paul vorschlägt, ist ungefähr das, was ich mir vorgestellt hatte, aber mit einer Ja/Nein-Aufforderung, anstatt mit einer Fehlermeldung auszusteigen. Diese beiden Ansätze haben Vor- und Nachteile (hauptsächlich in Bezug darauf, wie sie fehlschlagen, wenn sie von einem anderen Skript aus aufgerufen werden).

Wäre es möglich, Python so etwas wie sys.localprefix hinzuzufügen (ich sehe hier python-dev)?
Sys.localprefix wäre standardmäßig sys.prefix. Distributionen könnten es genauso definieren wie sie Präfixe definieren (zB prefix = '/usr', localprefix='/usr/local'). Pip und easy_install würden sys.localprefix als Speicherort für die Installation verwenden, wenn sie als sudo verwendet werden, wenn sie nicht über ausreichende Rechte verfügen, greifen Sie auf --user zurück.

Wir haben so etwas mit "Gem Install" in Fedora 17 gemacht und Ruby-Entwickler waren im Allgemeinen sehr zufrieden damit, also dachte ich, ich würde es teilen:

  • "gem install foo" installiert "foo" in ~/somedir wenn uid != 0
  • "gem install foo" installiert "foo" in /usr/local/somedir, wenn uid == 0
  • "yum install rubygem-foo" installiert das RPM-gepackte "foo" in /usr/somedir

Ich denke, dass die Wahl des Installationsverzeichnisses basierend auf Benutzerrechten für die Leute sehr verwirrend wäre; "pip install foo" sollte für alle Nicht-Root-Benutzer auf die gleiche Weise funktionieren. Wenn Sie die Mehrheit der Benutzer in Betracht ziehen, möchten sie "pip install" in ihr Zuhause und "sudo pip install" in ein systemweites Verzeichnis. Daher denke ich, dass es der beste Ansatz ist, dies basierend auf uid wie oben gezeigt zu tun - und für diejenigen Benutzer, die nicht root sind, aber in ein systemweites Verzeichnis installieren möchten, gibt es immer die Option --target.

@bkabrda Das ist eine einfache Wahl, solange Sie sich keine Sorgen über das Hinzufügen von Skripten zu $PATH machen. Was hast du dort gemacht?

@Ivoz wie von @dstufft bemerkt , hat Fedora bereits $HOME/.local/bin auf PATH, also hat alles sofort funktioniert (Apropos Skripte).

Slaveks Vorschlag klingt für mich gut für POSIX-Systeme. Es sollte auch gut mit Containern funktionieren, da Sachen, die in einem Container laufen, gesagt werden können, dass sie denken, es sei uid 0, obwohl es etwas ganz anderes von außerhalb des Containers ist.

Bei Windows bin ich mir weniger sicher, was die richtige Antwort ist. Wir haben nicht das gleiche Problem damit, mit dem Systempaketmanager in Streit zu geraten, obwohl er bis zu einem gewissen Grad existiert (pip install vs. MSI-Installer), und haben die zusätzliche Komplikation, dass selbst in Python 3.4 der optionale PATH des Installers vorhanden ist Modifikationen fügen nur das globale Scripts-Verzeichnis hinzu, nicht das Verzeichnis pro Benutzer.

Windows ist auch seltsam, je nachdem, ob Python am Standardspeicherort (unkontrolliert) oder in Programmdateien installiert ist (UAC-Berechtigungsausweitung erforderlich, um Änderungen vorzunehmen).

Die von @rkuska vorgeschlagene "localprefix" -Idee sieht für mich gut aus, einfach und leicht. Außerdem mag ich den Ansatz, den @bkabrda vorschlägt, besonders für Distributionen wie Arch, die Python 3.x zum Standard-Python machen.

Eine weitere Anmerkung ist, dass Arch in der Version 3.4.0, genau wie Debian, surepip deaktiviert hat (hauptsächlich, weil wir die neuesten Versionen von setuptools und pip bereitstellen wollen, während die gebündelten Versionen für Ewigkeiten veraltet sein können), also wäre es schön, es zu haben ein tipp dazu.

@lvoz
Für Arch haben wir keinen Pfad unter $HOME zu PATH hinzugefügt, aber ich finde es immer noch in Ordnung. Wir haben bereits einen Wiki-Eintrag für Ruby , der den Benutzer auffordert, ihn hinzuzufügen.

Es wäre schön, wenn die Arch- und Debian-Entwickler Slavek bei der Arbeit an seinem Patch helfen würden, anstatt es nur zu deaktivieren, damit surepip ein Rad aus den Systemversionen rekonstruiert und in virtuellen Umgebungen installiert.

Nur zu Ihrer Information, wir haben bereits funktionierende Python 3.4 RPM-Builds in Fedoras Copr-Build-System (Testen, nicht ratsam, sie zu installieren, wenn Sie nichts kaputt machen wollen). Wenn Sie mehr darüber wissen wollen, wie wir das angehen, werfen Sie einen Blick auf den Code usw., sehen Sie sich meine Diskussion mit Barry Warsaw [2] auf debian-python ML an.
(Unsere Patches brauchen noch etwas Liebe, bevor wir sie vorschlagen, aber für uns nachgelagerte Geldautomaten funktioniert alles gut.)

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

Tut mir leid, aber AFAIK Arch hat das Rad nie unterstützt, und wir wollen auch nicht, dass der Paketmanager von surepip aufgerufen wird (korrigieren Sie mich jedoch, wenn ich diesen Ansatz falsch verstehe).

Für surepip wäre es jedoch eine nette Idee, den Benutzer zu warnen, pip nicht mit Hilfe von surepip zu installieren, und das ist das Beste, was mir im Moment einfällt.

Unser surepip wird niemals den Paketmanager aufrufen. Kurz gesagt, Fedoras surepip wird sich auf systempaketierte Setuptools und pip verlassen, um immer vorhanden zu sein (unser python3-Paket wird davon abhängen, was eine Abhängigkeitsschleife erzeugt, aber wir können damit umgehen) und wenn der Benutzer eine neue virtuelle Umgebung erstellt, wird es neu gepackt System-Setup-Tools und Pip in Wheels und installieren Sie sie in der neuen Virtualenv.
Wir schweifen langsam vom Thema ab, also sollten wir diese Diskussion woanders fortsetzen...

@felixonmars Bedeutet das, dass auf Arch venv genauso kaputt ist wie auf Debian?

OK, danke für die Erklärung, ich glaube, ich habe die Idee verstanden. Ich werde sehen, was ich tun kann, und debian-python dafür weiterverfolgen.

@dstufft Ja, die gebündelte Version wurde anstelle der Systemversion installiert.

@bkabrda Das löst also das Problem, wenn Sie pip mit einem System-Python aufrufen, wir müssen in diesem Fall den Sonderfall virtualenv/venv verwenden (was nicht das Ende der Welt ist). Aber es bedeutet auch, dass wir davon ausgehen, dass alle Pythons System-Pythons sind, sogar solche, die vom Benutzer in seinem Homedir installiert wurden, wie z. B. mit https://github.com/yyuu/pyenv (so führe ich Python tatsächlich aus). Ich bin mir also nicht sicher, deshalb dachte ich an die Berechtigungsprüfung.

dito was @dstufft gesagt hat, bei der Verwendung eines Tools wie pyenv zum Jonglieren von Nicht-Root-Pythons wäre es ziemlich seltsam, wenn root der Schlüssel für eine globale Installation wäre (wobei "global" != "System")

Wir haben so etwas mit "gem install" in Fedora 17 gemacht

Sie meinen, die Drehzahl von gem für Fedora 17 hat dies als Distributions-Hack? Oder hat gem selbst diese Logik?

Ein Gedanke ist, dass pip einen "systemfreundlichen Modus" bereitstellen sollte, der von Distributionen aktiviert werden kann, die pip paketieren, oder wenn Benutzer wissen, dass sie pip selbst in einem vom System verwalteten Python installieren. Andernfalls führt pip seine normale standardmäßige globale Logik aus.

Ah @felixonmars Ich habe gerade https://projects.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/python gesehen, wenn du nur --without-ensurepip anrufst, ist das in Ordnung . Dadurch bleibt das surepip-Modul für das venv-Modul intakt. Die Patches, die Ubuntu (Debian?) derzeit installiert hat, rufen tatsächlich rm -rf auf dem surepip-Paket selbst auf, wodurch es nicht verfügbar ist, um innerhalb eines venv aufgerufen zu werden.

Ich denke, standardmäßig auf Benutzerinstallationen zu setzen, wurde von Nick vor zwei Jahren vorgeschlagen, oder vielleicht von jemand anderem vor längerer Zeit, aber der Thread ging in viele Richtungen und war nicht fruchtbar. Das Haupthindernis war die Abwärtskompatibilität von IIRC, aber heutzutage sind Sysadmins und Pip-Benutzer möglicherweise eher daran gewöhnt, mit virtualenv/pip/setuptools-Updates vorsichtig zu sein, im Guten wie im Schlechten. Ich kann mich nicht erinnern, ob diese Diskussion auf distutils-sig oder pypa-dev stattfand.

@dstufft Oh, ich verstehe ... Aber ich fühle mich immer noch falsch, eine gebündelte (vielleicht alte) Version installiert zu haben, während systemseitig Pakete installiert sind :)

@felixonmars Nun , das Problem ist, dass Sie ein Systempaket nicht in einer virtuellen Umgebung installieren können, afaik :) (Und selbst wenn Sie könnten, gibt es unterschiedliche Bedenken, was Sie in einem Systempaket und in einer virtuellen Umgebung wollen.)

@dstufft Hier setzt Slaveks Rewheel an, aber das ist ein bisschen off-topic :)

@dstuff Danke!

Ich bin mir nicht sicher, ob ich die Diskussion dort fortsetzen soll, denn das sollte kein Problem sein, da wir Pip in Arch nicht entbündelt haben und Rewheel ein brauchbares Rad erzeugen sollte :)

@dstufft du hast recht, dass wir wahrscheinlich virtualenv und möglicherweise sogar pyenv spezialisieren müssten, was hässlich erscheint. Ich muss zugeben, dass ich mit pyenv nicht so vertraut bin, daher fällt mir derzeit keine "richtige" Lösung dafür ein. Ich werde versuchen, mir das genauer anzusehen und mir etwas einfallen zu lassen.

@qwcode für "gem install" auf Fedora, es ist ein Downstream-Patch. TBH Ich habe Fedoras Rubygems nicht lange berührt, aber das letzte Mal, als ich nachgesehen habe, war es nur stromabwärts.

Ich habe einen Link zu diesem Problem zu einem verwandten Fehler in Python [1] gepostet. Ich würde diese Diskussion gerne in den Python-Kern verschieben, um einen konfigurierbaren Speicherort für lokale Installationen von nicht nur pip , sondern auch easy_install und python setup.py install zu haben, danach könnte pip ( zB) sys.localprefix dir, wenn uid==0 und im Benutzerverzeichnis installieren, wenn uid!=0 wie @bkabrda erwähnt.

Im Moment bin ich damit einverstanden, dass Pip standardmäßig im Benutzerverzeichnis installiert wird.

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

Wie Nick betonte, habe ich die Diskussion von issue1298835 nach pypa-dev [1] verschoben.
[1] https://groups.google.com/forum/#!topic/pypa -dev/r6qsAmJl9t0

Standardmäßig --user

Gute Idee!

pip install foo gibt einen Fehler aus, weil es keine Dateiberechtigungen hat. Dies führt dazu, dass Benutzer stattdessen sudo pip install foo ausführen, das global auf dem System Python installiert wird

Es ist noch schlimmer. Viele Personen (z. B. Benutzer eines Universitätscomputernetzwerks) haben keine sudo-Berechtigungen. Wenn pip mit einem Berechtigungsfehler fehlschlägt, werden sie entweder:

  1. Senden Sie eine E-Mail an ihren Administrator und bitten Sie ihn, das Paket zu installieren. Das ist langsam und mühsam für alle.
  2. Aufgeben und auf das Paket verzichten.

Nur wenn sie besonders erfahren oder gut informiert sind, werden sie es pip install --user versuchen.

Wenn wir uns am Ende gegen 'default to --user' entscheiden, sollten wir die weniger störenden Alternativen in Betracht ziehen:

  1. Fallback auf --user (wenn die Installation aufgrund von Berechtigungsfehlern fehlschlägt)
  2. (Wenn die Installation aufgrund von Berechtigungsfehlern fehlschlägt), ermutigen Sie den Benutzer (in großen freundlichen Buchstaben), es mit --user zu versuchen

Ich benutze --user schon seit einiger Zeit in all meinen Installationen, aber im Allgemeinen ist sich die Leute dieser Option nicht bewusst. Ich stimme zu, dass es ärgerlich ist, den Berechtigungsfehler jedes Mal zu sehen, wenn Sie die Option vergessen. Ich habe jedoch festgestellt, dass Benutzerinstallationen nicht mit conda kompatibel sind (conda/conda#448).

Ich möchte dies wiederbeleben, da die Leute unter Windows viel öfter darauf stoßen werden, jetzt, wo 3.5 standardmäßig in Programmdateien installiert wird (was Administratorrechte zum Ändern erfordert).

Ich mag die Option "Fallback to --user on permission error" am besten für Installationen, mit "default to --user and fallback to system" bei Deinstallationen und füge vielleicht eine --system oder --system-only Option hinzu um den Rückfall zu verhindern. Benutzer, die pip absichtlich mit Administratorberechtigungen ausführen, erhalten wie erwartet eine Systeminstallation, und derzeit erhalten Benutzer ohne Berechtigungen eine Fehlermeldung, daher glaube ich nicht, dass es hier Probleme mit der Abwärtskompatibilität gibt.

Mein Ziel ist es, dass ein uninformierter Benutzer pip install spam; python -c "import spam" ohne Fehler ausführen kann (obwohl möglicherweise eine Warnung angezeigt wird, wenn er es mit --user erneut versucht).

Ich habe in letzter Zeit darüber nachgedacht, besonders seit #2403 und #2401 kürzlich geöffnet wurden, was mich dazu gebracht hat, über die Verwendung von sudo pip install nachzudenken und wie dies oft Systeme außer den Berechtigungsproblemen beschädigen kann.

Zu diesem Zweck frage ich mich, ob das bessere Endziel nicht nur darin besteht, dass --user der Standardwert ist, keine magischen Berechtigungsprüfungen, und ein neues Flag wie --global , --system hinzufügen, oder --no-user , wodurch das vorherige Verhalten wiederhergestellt wird. Dies ist einfacher zu erklären, da es das gleiche Verhalten hat, egal wie/wo die Dinge installiert sind.

Nun, wenn wir uns entscheiden, dass dies der Weg ist, den wir gehen wollen, bleibt immer noch das Problem, wie wir von dem, wo wir heute sind, zu diesem Punkt gelangen. Offensichtlich wird die Standardeinstellung an jedem Punkt, an dem wir wechseln, eine ziemlich große bahnbrechende Änderung sein, sodass wir eine ziemlich lange Vorlaufzeit benötigen werden. Ich denke, wenn wir uns für diesen Weg entscheiden, wäre es am besten, die Option --user weiterhin beizubehalten, eine neue Option wie --global hinzuzufügen und dann, wenn eins oder das andere Option ist nicht konfiguriert. Führen Sie die Berechtigungsprüfungsmagie durch, über die wir gesprochen haben, und wenn die Magie entschieden hat, das --global -Verhalten zu verwenden, werden wir eine sehr laute Verfallswarnung auslösen. Diese Abwertungswarnung würde viel länger bestehen bleiben als unsere anderen Abwertungen, die wir herausgegeben haben, da dies eine ziemlich große Verhaltensänderung wäre. Ich denke, wir würden auch eine Option hinzufügen wollen, die den magischen Fallback ausschaltet und das zukünftige Verhalten implementiert, damit die Leute dieses Verhalten heute erhalten können.

Eine weitere wichtige Frage ist, was wir tun sollen, wenn wir feststellen, dass das Python, in das wir installieren, keine Benutzerseiten aktiviert hat. In diesem Fall würde ich einfach sagen, dass --user ein Fehler ist, und für diese Pythons werden wir einfach auf die Standardeinstellung --global . Dies würde meines Erachtens automatisch virtualenv/venv abdecken, und wenn jemand eine "schwerere" isolierte Umgebung mit vollständig kompilierten Pythons haben möchte, kann er einfach site.py patchen, sodass er ENABLE_USER_SITE auf False setzt

+1, und ich würde für --system stimmen.

Ich werde bemerken, und ich bin sicher, dass Sie das lieben werden, die Ubuntu-Standardeinstellung hat sich geändert:

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

Am 09.02.2015 um 16:41 Uhr schrieb Donald Stufft:

Zu diesem Zweck frage ich mich, ob das bessere Endziel nicht nur darin besteht, dass --user das ist
Standard, keine magischen Berechtigungsprüfungen, und fügen Sie ein neues Flag wie --global hinzu,
--system oder --no-user , wodurch das vorherige Verhalten wiederhergestellt wird. Dies
ist den Leuten leichter zu erklären, da es das gleiche Verhalten hat, egal
wie/wo Dinge installiert sind.

Ich denke, dass --system falsch ist, weil das wirklich nur für einige Pythons gilt. Es gilt nicht für:

  • Python unter Windows
  • pyenv hat Pythons installiert
  • Conda hat Pythons installiert
  • Nix installierte Pythons
  • Benutzerdefinierte kompilierte Pythons.

Es gilt _nur_ auf *nix-Systemen, auf denen Python zufällig vom System ausgeliefert wird. Ich denke, --global ist ein viel besserer Name für diese Flagge.

Und FML, warum hat Debian/Ubuntu das Bedürfnis, ständig zufällige Patches hinzuzufügen, die erwartete Anwendungsfälle brechen?

Wenn also der Ubuntu-Patch zurückgesetzt wird, wie sieht der Zeitplan für die Fehlerbehebung hier aus? Eine Woche/einen Monat/3 Monate/6 Monate/ein Jahr...?

Kommt darauf an, was man unter fix versteht.

Angenommen, wir verwenden die Idee, die ich vor 2 Beiträgen hatte (die noch von den anderen Pip-Entwicklern abgesegnet werden muss), könnten wir wahrscheinlich ziemlich schnell den Übergangsplan erhalten, in dem Folgendes zutrifft:

  • Wenn --user übergeben wird, installieren wir _immer_ in die Benutzer-Site-Pakete.
  • Wenn --global (oder was auch immer) übergeben wird, installieren wir _immer_ in die globalen Site-Pakete.
  • Wenn keines der beiden bestanden wird, implementieren wir eine Fallback-Methode, die:

    • Erkennt, ob wir uns in einer virtuellen Umgebung befinden, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    • Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    • Erkennt, ob der effektive Benutzer keine Schreibberechtigung für sys.path hat und sich nicht so verhält, als ob --user übergeben wurde.

    • Wenn alle anderen Erkennungsmethoden fehlgeschlagen sind, tun Sie schließlich so, als ob --global übergeben wurde, und geben Sie eine Verfallswarnung aus, die besagt, dass sich das Verhalten irgendwann in der Zukunft ändern und stattdessen in --user installieren wird.

Dies wird niemanden davon abhalten, sudo pip install foo in sein System-Python einzugeben, es wird jedoch eine Warnung ausgeben, dass dies irgendwann --user bedeuten wird, und ihn dazu auffordern, explizit --global zu verwenden

  • Wenn --user übergeben wird, installieren wir _immer_ in die Benutzer-Site-Pakete.
  • Wenn --global (oder was auch immer) übergeben wird, installieren wir _immer_ in die globalen Site-Pakete.
  • Wenn keine der Optionen übergeben wird, implementieren wir eine Fallback-Methode, die:

    • Erkennt, ob wir uns in einer virtuellen Umgebung befinden, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    • Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    • Schließlich verwendet --user als Standard.

Der Übergang vom ersten Verhalten zum zweiten Verhalten wird jedoch einen ziemlich langen Zeitrahmen haben. Das wird eine wirklich große bahnbrechende Änderung sein, die die Dinge für jede Software (wie Salt, Chef, Puppet) oder Bereitstellungsskript (wie benutzerdefinierte einmalige Fabric-Skripte, die in Tausende von Projekten auf der ganzen Welt integriert sind) kaputt machen wird, die dies erwarten sudo pip install <foo> wird im globalen Python installiert. Wir müssen den Leuten eine lange Vorlaufzeit geben, damit sie die Warnung sehen, und ihre Software und Skripte so ändern, dass sie ein explizites --global -Flag weitergeben, wenn sie dieses Verhalten tatsächlich benötigen.

Ich denke, Donalds vorgeschlagener Plan ist gut, obwohl wir, wenn das Pip-Team beschließt, diesen Ansatz zu übernehmen, auch ein 3.5-Release-Blocker-Problem bei CPython melden sollten, damit das Pro-Benutzer-Skriptverzeichnis zusammen mit dem globalen zum Pfad unter Windows hinzugefügt wird ein. Wenn 3.5 dies zusammen mit dem Wechsel zur standardmäßigen Installation in Programmdateien hinzufügt, sollten wir das gewünschte Verhalten der Installation ohne Administratorberechtigungen erhalten, die weiterhin "einfach funktioniert".

Die Möglichkeit, den Standardinstallationsort über die Pip-Konfigurationsdateien zu ändern, kann ebenfalls nützlich sein, damit die Leute sich auf ihren eigenen Systemen für „per Benutzer standardmäßig“ entscheiden können, auch wenn sich die Standardeinstellung noch nicht geändert hat. (z. B. "default-install=user" vs. "default-install=global")

@dstufft : Ich helfe gerne bei der Umsetzung Ihres Vorschlags, wie er zum Ubuntu-Fehler gesagt wurde, wenn Sie mich brauchen. Sobald wir dieses Verhalten im Trunk feststellen, werde ich den aktuellen Ubuntu-Patch natürlich zurückportieren und durch diesen ersetzen.

Halten Sie mich auf dem Laufenden, wenn Sie Hilfe benötigen.

Ich gebe +1 für den Plan von @dstufft . Aus den genannten Gründen würde ich --global als Namen wählen. Wir haben jetzt lange genug auf dem Zaun gesessen, packen wir es an.

O'n und +1 auf den Vorschlag von @ncoghlan , dass Python 3.5 das Benutzer-Site-Verzeichnis zu PATH unter Windows hinzufügt. Vermeiden wir weitere Stolpersteine ​​für diesen Übergang.

Ich gebe auch +1 für den Plan von @dstufft und +1 für --global , obwohl ich mich immer noch wundere, dass sudo pip install foo --global benötigt. Gibt es tatsächlich eine Notwendigkeit für root, Benutzer-Site-Pakete zu haben? Könnten wir in Sonderfällen rooten, um Site-Pakete standardmäßig zu deaktivieren? (Womit sudo pip install foo genauso funktionieren würde wie jetzt)

Ich habe noch nie jemanden gesehen, der --user für root mit dem aktuellen Stand verwendet hat, aber wenn jemand tatsächlich einen solchen Anwendungsfall kennt, würde ich es gerne wissen.

Ein Gedanke, der mir eingefallen ist, ist, wie das Benutzer-Site-Verzeichnis funktioniert, wenn mehrere Versionen von Python installiert sind.

Wenn ich pip install pytest --user in Python 2.7 und 3.4 (mit Python 3.4 mein Standard-Python) ausführe, welche Version wird der Befehl py.test ausführen? Ich habe den Verdacht, dass sich die beiden Installationen gegenseitig überschreiben, also ist es eine "letzte gewinnt"-Situation, was _nicht_ gut ist. Auch wenn es "der letzte gewinnt" ist und ich die 2.7-Version nach der 3.4-Version installiere, wie würde ich das beheben, um 3.4 wieder zum Standard zu machen?

Und was ist mit Deinstallationen? Betrachten Sie das folgende Szenario (ungetestet, da ich einen sauberen Computer einrichten müsste, wenn ich nicht riskieren wollte, meinen Haupt-Laptop zu beschädigen):

    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

Erstens, warum hat der zweite Befehl keine Warnung ausgegeben, dass eine vorhandene Datei überschrieben wird? Oder würde es? Ob ja oder nicht, habe ich irgendwelche Möglichkeiten, was zu tun ist?

Zweitens, würde die Deinstallation nicht fehlschlagen, weil die Prüfsumme von py.test.exe nicht mit dem Wert in der Datei RECORD übereinstimmen würde? Wenn es fehlschlägt, wie würde ich es deinstallieren? Wenn es nicht fehlschlägt, wird es meine Python 2.7-Kopie von pytest beschädigen (durch Löschen der exe)?

Und schließlich (vorerst!) Würde das Benutzerskriptverzeichnis vor oder nach dem Systemskriptverzeichnis in PATH stehen? Meiner Meinung nach sollte es danach gehen, da sonst eine Benutzerinstallation eines Pakets in einem Python, das vom Benutzer _nicht_ als "Standard-Python" angefordert wurde, dasselbe Paket überschreiben könnte, das in den System-Site-Paketen des "Standard"-Python installiert ist.

Hmm, vielleicht gibt es noch einige offene Fragen, die geklärt werden müssen, bevor wir diese Änderung vornehmen ...

Ich würde erwarten, dass die Namenskonflikte im freigegebenen Windows-Benutzerskriptverzeichnis genauso behandelt werden, wie sie auf POSIX-Systemen mit ihren freigegebenen bin-Verzeichnissen behandelt werden: Python 3 würde den nicht qualifizierten Skriptnamen für installierte Pakete nicht installieren, also den nicht qualifizierten name würde sich auf die Python 2-Version beziehen.

Das Gleiche gilt dafür, ob die Systeminstallation oder die Installation pro Benutzer standardmäßig Vorrang hat: Legen Sie das Benutzerskriptverzeichnis nach dem Systemverzeichnis ab.

"Python 3 würde den nicht qualifizierten Skriptnamen für installierte Pakete nicht installieren" - vermutlich meinen Sie, dass Pip und Setuptools (unter Python 3) dies hier nicht tun würden? Das ist also eine Änderung an diesen Tools?

Oh, und blöd. Mein Muskelgedächtnis ist zu 100% darauf trainiert, "pip install foo" einzugeben, um es in meinem Standard-Python (3.4) zu installieren. Das wird die Hölle umzuschulen.

Außerdem können Windows-Benutzer wählen, ob „Python“ Python 2 oder 3 bedeutet (über „Make this the default Python“ und „Add to PATH“) – im Gegensatz zu Unix-Benutzern, bei denen das System Python die Regeln macht. Wenn ich also sage, dass ich Python 3.5 zu meinem Standard machen möchte, warum sollte sich „pip“ (oder ein anderer nicht qualifizierter Name) nicht auf diese Version beziehen? Es scheint bizarr, dass ein Benutzer, auf dem nur Python 3.5 unter Windows installiert ist, keine unqualifizierten Namen verwenden kann, nur weil ein Unix-Problem damit zusammenhängt, wie das System Python Namen benötigt. (Entschuldigung, wenn meine Beschreibung der Unix-Einschränkungen ungenau ist - ich verstehe das Problem dort nicht wirklich). Leute, die mehrere Python-Versionen installieren, brauchen eine Lösung, aber diese Lösung sollte die Mehrheit nicht betreffen, die nur eine Version benötigt.

Vielleicht ist die einfachste Antwort, dass das Verzeichnis der Benutzerskripte versioniert werden sollte, genau wie das Verzeichnis der Benutzerseitenpakete?

Oh, und sollte diese Debatte eher auf python-dev als hier stattfinden, da es allgemeiner um das Benutzer-Site-Verzeichnis geht?

Es wäre sicherlich vernünftig, die PEP 370-Designdiskussion für das Windows-Verzeichnis für benutzerspezifische Skripts auf python-dev erneut zu öffnen. Es ist seltsam, dass globale Skriptinstallationen unter Windows durch die Python-Version begrenzt sind, Skriptinstallationen pro Benutzer jedoch nicht.

Das steht im Gegensatz zu der Situation auf POSIX, die auf beiden Ebenen (global oder pro Benutzer) konsequent einen gemeinsam genutzten Namensraum für ausführbare Dateien verwendet, sodass Namenskonflikte eher zur Installationszeit auftauchen als durch Namensschatten zur Laufzeit.

Was die allgemeine Lösung für die Handhabung der parallelen Installation angeht, wäre das der "-m"-Schalter - auf diese Weise wissen Sie immer, welches Python Sie aufrufen, anstatt über den Inhalt der Shebang-Zeile eines separaten Skripts zu raten.

Zu -m verstanden, aber das letzte Mal, als das im Zusammenhang mit der Dokumentation von Dingen angesprochen wurde, war die starke Präferenz, dass wir pip install foo als die kanonische Methode zur Installation von Dingen behandeln sollten (mit -m und versionierte Befehle werden als Ausnahmen für Spezialfälle behandelt.

Das Pip-Handbuch _erwähnt_ nicht einmal Alternativen (außer in dem einen Fall, in dem -m verwendet wird, um Pip selbst unter Windows zu aktualisieren).

Ich empfehle -m in der stdlib-Paketdokumentation für die Handhabung des Pip-Aufrufs, wenn
Umgang mit parallelen Python-Installationen - es ist der einzige Aufrufstil, der
funktioniert auf allen Plattformen, für globale Installationen, Benutzerinstallationen und virtuell
Umgebungen.

Am 09. Februar 2015 um 19:58 Uhr schrieb ncoghlan:

Möglichkeit, den Standardinstallationsort über die Pip-Konfigurationsdateien zu ändern
kann auch nützlich sein, um es den Leuten zu ermöglichen, sich für "pro Benutzer standardmäßig" zu entscheiden
ihre eigenen Systeme, auch wenn sich die Standardeinstellung nicht geändert hat
noch. (z. B. "default-install=user" vs. "default-install=global")

Ich mag das. Eines der Dinge, mit denen wir zu kämpfen haben, ist die Lösung
Upstreams konservativerer Ansatz zur Migration zu einem --user default, with
Distributionen konkurrierende Ziele, Pip-Systeme sicher und konsistent mit anderen zu machen
Werkzeuge. Z.B

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

Wenn wir eine systemweite Konfigurationsdatei hätten, um den Standard auszuwählen, dann at
zumindest alle beteiligten Maschinen wären identisch, und die Distributionen wären es nicht
hässliche Deltas tragen müssen. Alles, was wir tun müssten, wäre, die zu ändern
config-Datei und dokumentieren Sie dies für unsere Benutzer. Probleme, die verursacht werden würden
unsere zu handhaben, aber zumindest wäre es leicht zu erklären.

Ich glaube nicht, dass Debuntu derzeit eine Site-weite pip.conf-Datei installiert (ich werde es haben
zu überprüfen).

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

Eine Komplikation: Wir installieren verschiedene Pip-Skripte für Python 2 und Python 3,
Ich denke also, wir bräuchten separate Konfigurationsdateien für die verschiedenen Versionen von
Python, zB /etc/{xdg/pip/}/pip{2,3}.conf oder ähnliches.

Am 10. Februar 2015 um 01:24 Uhr schrieb Paul Moore:

Ein Gedanke, der mir eingefallen ist, ist, wie das Benutzer-Site-Verzeichnis funktionieren wird
mehrere Versionen von Python installiert?

Auf Debian/Ubuntu (vielleicht alle *nixes?) haben wir keine Kollision, weil die
Bibliotheken werden in ~/.local/lib/pythonX.Y/site-packages installiert

Wir _bekommen_ aber Kollisionen auf ~/.local/bin. Installieren eines Pakets mit a
script 'foo' mit pip install --user foo und pip3 install --user foo will
am Ende das Skript ~/.local/bin/foo vermasseln.

Ein Nachteil dieser Änderung ist, dass ich denke, dass Fedora die einzige Downstream-Distribution ist, die standardmäßig ~/.local/bin zu $PATH hinzufügt (und es sollte einfach vor /usr/bin und /usr/local/bin kommen wie die Benutzer-Site-Pakete vor Site-Paketen kommen). Im Idealfall können nachgelagerte Unternehmen ihre Systeme so ändern, dass ~/.local/bin standardmäßig auf $PATH liegt.

Am 10. Februar 2015 um 07:24 Uhr schrieb Donald Stufft:

Ein Nachteil dieser Änderung ist, dass Fedora meiner Meinung nach der einzige Downstream ist
Distribution, die standardmäßig ~/.local/bin zu $PATH hinzufügt (und es sollte kommen
vor /usr/bin und /usr/local/bin genau wie die User-Site-Pakete kommt
vor Site-Paketen). Im Idealfall können nachgeschaltete Unternehmen ihre ändern
so, dass ~/.local/bin standardmäßig auf $PATH liegt.

Ja, aber darüber können wir separat entscheiden. (Oder eher stromabwärts
Distributionen können das.)

(und es sollte genau wie der Benutzer vor /usr/bin und /usr/local/bin stehen
Site-Pakete kommen vor Site-Paketen)

Hmm, @ncoghlan hat gerade das Gegenteil gesagt, dass (insbesondere unter Windows
Kontext) sollte das Benutzerskriptverzeichnis _hinter_ dem Systemverzeichnis liegen. Welcher
Ich stimme dem zu, solange das Benutzerskriptverzeichnis nicht versioniert ist. Wenn es
versioniert, mache ich mir weniger Sorgen. Aber das spiegelt wahrscheinlich die Tatsache wider, dass
Windows-Benutzer mussten nie Konflikte mit unversionierten Skripten ertragen
Monstrositäten wie pip2/pip3, wie Unix-Benutzer es getan haben ;-)

Oh, und das Skript-Clobbering-Ding ist ein allgemeineres Problem, das nicht wirklich genau mit --user zusammenhängt. Das gleiche Problem besteht überall außer bei Windows --global -Installationen. Ich denke, die Lösung dieses Problems ist ein zweitrangiges Anliegen/Problem, das wir getrennt von diesem Problem lösen sollten.

Also aktuelle Gedanken:

  • Ich denke, es besteht Einigkeit über die allgemeine Idee, die ich zuvor gepostet habe, also denke ich, dass wir mit so etwas weitermachen wollen.
  • Wir werden das Flag --global verwenden.
  • Wir möchten wahrscheinlich eine Art Warnung, wenn wir in --user installieren und ~/.local/bin nicht auf $PATH ist.
  • Wir wollen eine Art default-install Option, die das Fallback-Verhalten im Wesentlichen deaktiviert und einfach entweder auf --global oder --user .
  • Ab pip 6.0 haben wir maschinenspezifische Konfigurationsdateien, die sich in /etc/ befinden, diese sind jedoch nicht spezifisch für die Version von Python, die pip ausführt. Ich denke, das ist ein gutes Feature, wenn auch etwas separat (und könnte auch mit der Lösung des Skript-Clobbering-Dings einhergehen).

Eine große offene Frage sehe ich noch: Was wollen wir langfristig tun, wenn jemand sudo pip install foo macht bzw. wenn jemand die Berechtigung hat, in das site-packages -Verzeichnis zu schreiben?

Die Möglichkeiten die mir einfallen sind:

  1. Installieren Sie in --global . Dies ist die abwärtskompatibelste Option und stellt wahrscheinlich dar, was Benutzer erwarten, wenn sie das eingeben. Es hat jedoch den Nachteil, dass es (stillschweigend) mit dem globalen Python durcheinander kommt, was auf vielen Systemen zu Systemabstürzen führen kann.
  2. Installieren Sie in --user , dies schützt vor kaputten Systemen (glaube ich?), aber ich glaube nicht, dass irgendjemand erwarten würde, dass der Root-Benutzer eine /root/.local/ -Installation erhält.
  3. Geben Sie einfach einen Fehler aus und fordern Sie den Benutzer auf, entweder --user oder --global manuell auszuwählen.
  4. Wählen Sie eine der ersten beiden Optionen aus, aber stellen Sie einen Schalter bereit, den Distributionen in /etc/ abgeben können, der die dritte Option aktiviert.

Die vierte Option könnte die beste sein, aber ich denke, wir sollten zuerst versuchen, eine der anderen Optionen auszuwählen, wenn wir zu einer Lösung kommen können, die auf allen Plattformen/Szenarien gleich funktioniert und auf allen Sinn macht wie ich würde es vorziehen, wenn möglich, ein konsistentes plattformübergreifendes Verhalten zu haben.

Ich denke, dass die dritte Option wahrscheinlich schlecht ist, da "Ich habe Schreibberechtigung" das Szenario sein wird, in dem jeder unter Windows vor Python 3.5 ist oder jeder, der Conda verwendet, oder jeder, der pyenv verwendet. Fehler zu machen scheint in all diesen Fällen das Falsche zu sein und ist obendrein etwas benutzerunfreundlich.

Ich denke, zwischen 1 und 2 kommt es wirklich darauf an, wie schlecht es unserer Meinung nach ist, wenn Leute (konzeptionell) sudo pip install --global foo tun. Unter Windows, Conda, pyenv usw. lautet die Antwort darauf meiner Meinung nach "wir glauben nicht, dass es überhaupt eine schlechte Praxis ist". Auf * nix denke ich, dass die Antwort vielleicht lautet: "Benutzer sollten mit ihrem System tun dürfen, was sie wollen, aber wir sollten Schienen bereitstellen, um sie von "schlechten" Dingen wegzuführen".

Wenn ich also mehr darüber nachdenke, denke ich, dass ich mich für die erste Option entscheiden müsste, die die richtige Option für uns ist. Das löst die Abwärtskompatibilitätsprobleme mehr oder weniger, da das Verhalten, das wir wirklich ändern würden, darin besteht, dass Sie, wenn Sie pip install foo ohne Erlaubnis zur Installation in diese globalen Verzeichnisse eingeben, statt in --user installieren würden einen Fehler auslösen. Ich denke, dass es unwahrscheinlich ist, dass irgendjemand da draußen wirklich davon abhängig ist, dass Pip in diesem Fall einen Fehler meldet. Ich denke auch, dass pip install --user als Root-Benutzer wahrscheinlich nicht das ist, was irgendjemand erwartet oder will, und es ist wirklich nur eine Fußwaffe für Benutzer.

Dann wäre mein aktualisierter Vorschlag:

  • Wenn --user übergeben wird, installieren wir immer in die Benutzer-Site-Pakete.
  • Wenn --global übergeben wird, installieren wir immer in die globalen Site-Pakete.
  • Wenn keines der beiden bestanden wird, implementieren wir eine Fallback-Methode, die:

    1. Erkennt, ob wir uns in einer virtuellen Umgebung befinden, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    2. Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob --global übergeben wurde.

    3. Betrachtet default-install und verwendet, falls vorhanden, --user oder -global basierend darauf.

    4. Erkennt, ob der effektive Benutzer keine Schreibberechtigungen für globale Site-Pakete hat und sich nicht so verhält, als ob --user übergeben wurde.

    5. Wenn alle anderen Erkennungsmethoden fehlgeschlagen sind, verhalten Sie sich schließlich so, als ob --global übergeben wurde.

Dies würde bedeuten, dass es keinen Verfallszeitraum gibt und dass die Erwartung ist, dass wir in Abwesenheit von --user oder --global versuchen werden, basierend auf den Fähigkeiten des Python, in dem wir laufen, die beste Vermutung anzustellen , der effektive Benutzer und jede konfigurierte Standardinstallationsmethode.

(und es sollte genau wie der Benutzer vor /usr/bin und /usr/local/bin stehen
Site-Pakete kommen vor Site-Paketen)

Hmm, @ncoghlan hat gerade das Gegenteil gesagt, dass (insbesondere unter Windows
Kontext) sollte das Benutzerskriptverzeichnis _hinter_ dem Systemverzeichnis liegen. Welcher
Ich stimme dem zu, solange das Benutzerskriptverzeichnis nicht versioniert ist. Wenn es
versioniert, mache ich mir weniger Sorgen. Aber das spiegelt wahrscheinlich die Tatsache wider, dass
Windows-Benutzer mussten nie Konflikte mit unversionierten Skripten ertragen
Monstrositäten wie pip2/pip3, wie Unix-Benutzer es getan haben ;-)

Ich denke nicht einmal daran, dass die Skriptnamen kollidieren. Ich denke nur, dass es völlig falsch ist, wenn sich unsere Variable $PATH anders verhält als sys.path . Soweit ich weiß, lautet die Reihenfolge sys.path : stdlib > Benutzer-Site-Pakete > Globale Site-Pakete. Ich denke, es wäre wirklich verwirrend, wenn die Reihenfolge some-script globales Bin-Verzeichnis > Benutzer-Bin-Verzeichnis wäre, während python -m some-script Benutzer-Site-Pakete > Globale Site-Pakete wäre.

Wenn es ein Problem mit den Skriptverzeichnissen gibt (und versionierte vs. nicht versionierte), dann sollten wir dieses Problem meiner Meinung nach beheben, aber es ist nicht besonders relevant für die Reihenfolge, in der sie sich befinden sollten, da ich mich nach etwas anderem fühle, als das zu vergleichen, was sys.path tut ist super falsch.

Guter Punkt, wir sollten davon ausgehen (und empfehlen), dass $PATH auf sys.path folgt, mit (in Windows-Begriffen) C:PythonXY vor %APPDATA%PythonXYScripts vor C:PythonXYScripts. Ich werde das im Python-Dev-Thread vermerken.

Donalds neuester Vorschlag klingt gut für mich (derselbe wie mein ursprünglicher Vorschlag plus alle wichtigen Details, die ich ausgelassen habe :) ). Ich stimme auch zu 100% dem Absatz "Also mehr darüber nachdenken ..." zu.

Das Konfigurieren von PATH unter Windows wird nahezu unmöglich sein. Ein systemweites Installationsprogramm kann nur systemweite Umgebungsvariablen konfigurieren und sie können keine Erweiterungen enthalten, sodass Sie nicht für jeden Benutzer unterschiedliche Pfade festlegen können. (Das Pro-Benutzer-Installationsprogramm kann dies tun, aber in diesem Fall wird --global erfolgreich sein und es besteht daher keine Notwendigkeit.)

Wegen der fehlerhaften Handhabung von PATH in Windows übertreffen systemweite Einstellungen _immer_ die Einstellungen pro Benutzer. Dies führte vor einiger Zeit zu meinem halben Vorschlag (auf python-dev, IIRC) über die Verwendung des py.exe-Launchers für nicht versionierte Skripte, sodass pip.exe immer zum neuesten System oder Benutzer-Python und nicht zum eine, die es installiert hat, und (z. B.) pip.exe -3.5 würde die Auswahl einer bestimmten Version ermöglichen.

Die einzige Möglichkeit, dies wirklich zum Laufen zu bringen, besteht darin, dass das Python-Installationsprogramm mit der Installation von Batchdateien beginnt, um PATH auf Anfrage zu konfigurieren (und möglicherweise eine Verknüpfung, die die Batchdatei ausführt). Das erste, was Benutzer eingeben würden, ist also activate-py35 und dann ist ihr PATH korrekt für 3.5 konfiguriert. Ich bin jedoch sehr hin und her gerissen, da ich nicht in die vcvarsall.bat-Situation geraten möchte, aber gleichzeitig ist es großartig für Skripte, die derzeit Annahmen über Installationsorte treffen oder versuchen, die Registrierung zu durchlaufen es zu finden.

und vielleicht eine Verknüpfung, die die Batchdatei ausführt

In meinen Augen ist dies eine Verknüpfung "Python 3.5 (32-Bit) Eingabeaufforderung". Benutzer von Visual Studio sollten die Parallele erkennen.

Ich weiß nicht genug über Windows, um die Auswirkungen all dessen vollständig zu verstehen, aber ich fühle mich ziemlich schlecht, wenn ich in eine Situation zurückkehre, in der pip install foo , das ein Skript foo installiert, nicht sofort sein kann ausgeführt als foo auf der Kommandozeile. Wenn wir auf --user installieren und das nicht standardmäßig auf ihrem Pfad ist, dann fühlt sich das für mich wie eine ziemlich große Regression an.

Ich bin mir nicht sicher, ob ich genau verstehe, wie die Verwendung py.exe für die nicht versionierten Skripte in der Praxis funktionieren würde und ob es das Problem tatsächlich lösen würde oder nicht. Ich bin persönlich nicht daran gebunden, Skripte genau so zu erstellen, wie wir es heute tun. Wenn es also _funktioniert_, denke ich, können wir es vielleicht tun, aber ich müsste die Auswirkungen besser verstehen, bevor ich mein +1 dafür geben kann.

Das Konfigurieren von PATH unter Windows wird nahezu unmöglich sein. Ein systemweites Installationsprogramm kann nur systemweite Umgebungsvariablen konfigurieren und sie können keine Erweiterungen enthalten, sodass Sie nicht für jeden Benutzer unterschiedliche Pfade festlegen können.

Oh, igitt. Das hatte ich vergessen.

und vielleicht eine Verknüpfung, die die Batchdatei ausführt
In meinen Augen ist dies eine Verknüpfung "Python 3.5 (32-Bit) Eingabeaufforderung". Benutzer von Visual Studio sollten die Parallele erkennen.

... was für diejenigen von uns schrecklich ist, die für alles auf Powershell zurückgreifen.

aber ich fühle mich ziemlich schlecht, wenn ich in eine Situation zurückkehre, in der pip install foo, das ein Skript foo installiert, nicht sofort als foo auf der Befehlszeile ausgeführt werden kann.

Einverstanden. Dies wäre eine schlechte Regression und muss angegangen werden. Ich wünschte nur, jemand hätte eine Möglichkeit :-)

Ich bin mir nicht sicher, ob ich genau verstehe, wie die Verwendung von py.exe für die nicht versionierten Skripts in der Praxis funktionieren würde

Ich denke, der Punkt (der nur etwas mit py.exe zusammenhängt) ist, dass der Exe-Wrapper den Interpreter dynamisch basierend auf "was ist irgendwie der Standard" (Registrierung, die py.exe INI-Datei, was auch immer Python %PATH% Ihnen gibt, ...). Ich bin mir jedoch nicht sicher, wie es helfen würde, da wir immer noch ein versioniertes Benutzerskriptverzeichnis benötigen (um zu vermeiden, dass Dateien sich gegenseitig überschreiben oder Dateien mit Interpretern ausgeführt werden, auf denen das Paket nicht installiert ist) und wir würden es immer noch tun kann das nicht an der richtigen Stelle in %PATH% einfügen.

... was für diejenigen von uns schrecklich ist, die für alles auf Powershell zurückgreifen.

Ich habe es gerade ausprobiert und kann problemlos activate-py35.bat - und activate-py35.ps1 -Dateien erstellen, die identisch aussehen und sich identisch verhalten (dh jeder muss nur activate-py35 schreiben und die Pfade aktualisieren). Immer noch nicht ideal, aber möglicherweise das Beste aus einer schlechten Situation.

Ich bin mir nicht sicher, ob ich genau verstehe, wie die Verwendung von py.exe für die nicht versionierten Skripts in der Praxis funktionieren würde

Ich denke, der Punkt (der nur etwas mit py.exe zusammenhängt) ist, dass der Exe-Wrapper den Interpreter dynamisch basierend auf "was ist die Vorgabe" irgendwie

Das "irgendwie" ist, wo py.exe ins Spiel kommt - die gleichen Regeln sollten verwendet werden. Wenn der Launcher aktualisiert würde, um seinen eigenen Namen zu überprüfen, könnte er anstelle von python.exe versuchen, stattdessen 'scripts\\{}{}.{}.exe'.format(argv[0], major_version, minor_version) zu starten (mit geeigneter Erweiterungstrimmung auf argv[0] usw.). Dann müssen Installer für den nicht versionierten Launcher eine andere Datei als für den vollständig versionierten (der von heute an unverändert bleiben würde) verwenden, aber diese Datei wäre nur die normale py.exe mit einem neuen Namen. (Dies hätte in den alten Tagen der pip-script.py -Dateien noch einfacher sein können, aber jetzt, wo diese weg sind ...)

Aber wie Sie sagen, PATH ist immer noch das Problem. Ich habe keine guten Lösungen, und nicht einmal so viele schlechte Lösungen. Umgebungsvariablen sind eigentlich für die Konfiguration durch Administratoren oder Benutzer gedacht, nicht für Installateure.

Wir können anpassen, wie wir Skripte installieren, um die Benutzererfahrung zu verbessern. Es ist alles eine Balance, die kombinierte .exe - und .py -Datei hat die Dinge für Benutzer angenehmer gemacht, da es nur die einzelne .exe -Datei gibt. Ich denke jedoch, dass es wichtiger ist, die beste Geschichte für pip install foo && foo zu bekommen, als diese bestimmte Sache, also wenn wir die .exe und die .py wieder trennen müssen, denke ich, dass das eine ist guter Kompromiss für eine gute Antwort.

Die .exe / .py Trennung ist das geringste Problem :)

Ich wärme mich gerade für die activate-py35 -Idee auf (oder akzeptiere sie widerwillig?). Ich war noch nie ein Fan davon, dass der Installer Python zu PATH hinzufügt, und der Befehl py -m pip hat nicht wirklich an Bedeutung gewonnen (und er würde beispielsweise auch nicht für Sphinx funktionieren). Ich schreibe eine detailliertere Beschreibung, wie activate-py funktionieren könnte, und poste sie an python-dev, um zu sehen, ob sie Zugkraft bekommt.

Würden diese activate-whatever -Dateien denen in der virtuellen Umgebung ähneln? Außer dass anstelle einer virtuellen Umgebung zu $PATH die echten Pythons hinzugefügt werden?

Ja, ziemlich identisch. Auf python-dev habe ich gerade vorgeschlagen, dass sie einen -x.y -Parameter nehmen, ihn an py.exe übergeben und sysconfig verwenden, um die Pfade zu erhalten.

OK. Ich habe keine Meinung darüber, wie schlimm das für Windows-Benutzer wäre, da ich keiner bin. Es klingt nicht absolut schrecklich (vielleicht?), Aber das ist ungefähr so ​​weit, wie mich meine Windows-Kenntnisse bringen können.

Am 10. Februar 2015 um 08:02 Uhr schrieb Donald Stufft:

Oh, und das Skript-Clobbering-Ding ist ein allgemeineres Problem, das es nicht ist
wirklich genau mit --user verwandt. Überall besteht das gleiche Problem
außer Windows --global installiert. Ich denke, die Lösung für dieses Problem ist
ein zweitrangiges Anliegen/Problem, das wir getrennt von diesem Problem lösen sollten.

Einverstanden.

Wir werden das Flag --global verwenden.

+1

Wir möchten wahrscheinlich eine Art Warnung, wenn wir in --user installieren und
~/.local/bin ist nicht auf $PATH .

+1, vielleicht mit einer Konfigurationsoption, um die Warnung zu unterdrücken?

Wir wollen eine Art default-install -Option, die im Wesentlichen funktioniert
Deaktivieren Sie das Fallback-Verhalten und codieren Sie einfach entweder auf --global oder
--user .

+1

Ab pip 6.0 haben wir maschinenspezifische Konfigurationsdateien, die sich in /etc/ befinden
Diese sind jedoch nicht spezifisch für die ausgeführte Version von Python
Pip. Ich denke, das ist ein gutes Feature, wenn auch etwas getrennt (und
könnte auch Hand in Hand gehen mit der Lösung des Script-Clobbering-Dings).

Ich würde eine Suchreihenfolge vorschlagen wie:

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

zuerst(?) in /etc/xdg/pip gerootet dann /etc, wobei XY natürlich das ist
Major.Minor-Versionsnummer. Wer zuerst gefunden wird, gewinnt.

Eine große offene Frage sehe ich noch: Langfristig, was wollen wir wann passieren
jemand tut sudo pip install foo oder besser gesagt, wenn jemand die Erlaubnis dazu hat
in das Verzeichnis site-packages schreiben?

Bitte beachten Sie, dass es nicht nur ein "site-packages"-Verzeichnis gibt. Zum Beispiel,
Auf Debian/Ubuntu wollen wir nicht, dass sudo pip install _überhaupt_ installiert wird
/usr/lib, aber nur /usr/local/lib. Und vergiss nicht, es sind dist-Pakete hier
keine Site-Pakete (außer in ~/.local aus $gründen).

Das ist wirklich ein wichtiger Punkt, der manchmal (auch von mir) vergessen wird.
Donald beschreibt es am besten, wenn er sagt, dass es ein Site-Local-Verzeichnis und ein
anbieterlokales Verzeichnis. Unter Debian ist site-local
/usr/lib/pythonX.Y/dist-packages und kein Pip-Befehl sollte das jemals berühren,
Vendor-Local hingegen ist /usr/local/lib/pythonX.Y/dist-packages und es ist a
dokumentierter und beliebter Anwendungsfall für einige Systemadministratoren zur Pip-Installation
in dieses Verzeichnis.

Was ich also vorschlagen würde, da wir bereits den Konfigurationsdateipfad heruntergefahren sind, ist zu
diese konfigurierbar machen, zB

  • globales_Installationsverzeichnis
  • global_install_as_sudo (wahr/falsch)
  1. Installieren Sie in --global . Dies ist die abwärtskompatibelste Option
    und stellt wahrscheinlich dar, was Benutzer erwarten, wenn sie das eingeben. Allerdings hat es
    der Nachteil, dass es (leise) mit dem globalen Python durcheinander kommt, was auf vielen
    Systeme können defekte Systeme verursachen.

Mit der obigen Konfigurierbarkeit wäre dies vollständig kompatibel mit Debian.
Debian-Superuser erwarten, dass sudo pip install hineingeht
/usr/local/lib/pythonX.Y/dist-packages. Ich würde nicht sagen, dass es "durcheinander bringt
system", weil es den Paketmanager nicht unterbricht und obwohl es das kann
vom System installierte Pakete außer Kraft setzen (die sich in
/usr/lib/pythonX.Y/dist-packages), tut dies auf eine definierte, dokumentierte Weise.

  1. Installieren Sie in --user , dies schützt vor kaputten Systemen (glaube ich?)
    aber ich glaube nicht, dass irgendjemand erwarten würde, dass der Root-Benutzer a bekommt
    /root/.local/ installieren.

Einverstanden, das wäre unerwartet.

  1. Geben Sie einfach einen Fehler aus und fordern Sie den Benutzer auf, entweder --user oder auszuwählen
    --global manuell.

Ich wäre damit einverstanden, aber siehe den Konfigurationsschalter oben.

  1. Wählen Sie eine der ersten beiden Optionen, aber stellen Sie einen Schalter zur Verfügung, den Distributionen können
    Geben /etc/ ein, wodurch die dritte Option aktiviert wird.

Hey, was für eine großartige Option!

Die vierte Option ist vielleicht die beste, aber ich denke, wir sollten es versuchen
Wählen Sie zuerst eine der anderen Optionen, wenn wir zu einer Lösung kommen können
das funktioniert auf allen Plattformen/Szenarien gleich und macht auf allen Sinn
da ich ein konsistentes plattformübergreifendes Verhalten bevorzugen würde, wenn möglich.

Ich bin damit einverstanden, dass ich ein anderes, plattformdefiniertes Verhalten habe, wenn, sagen wir, Pip hatte a
--dry-run-Option, die dem Benutzer zumindest genau mitteilt, was vor sich geht
zu tun und wo.

Ich denke, dass die dritte Option wahrscheinlich schlecht ist, da "Ich habe schreiben
Berechtigung" wird das Szenario sein, in dem sich jeder unter Windows auf Pre befindet
Python 3.5 oder jeder, der Conda verwendet, oder jeder, der pyenv verwendet. Fehler aus
scheint in all diesen Fällen das Falsche zu sein und ist so etwas wie ein Benutzer
unfreundlich obendrein.

Ich würde mich freuen, wenn die Standardkonfiguration --global install zulassen würde, wenn Sie
habe die Erlaubnis. Ich glaube nicht einmal, dass Debian es ändern würde (vielleicht haben andere es getan
andere Meinung, aber das gibt uns zumindest Optionen).

Ich denke also, zwischen 1 und 2 kommt es wirklich darauf an, wie schlecht eine Übung ist
wir denken, es ist Sache der Leute, (konzeptionell) sudo pip install --global foo zu tun.

Unter Debian ist es ein erwarteter Anwendungsfall, solange es nach /usr/local/lib geht.
Es kann nicht nach /usr/lib gehen.

(All dies beschreibt übrigens das Outside-a-venv-Verhalten.)

  • Wenn --user übergeben wird, installieren wir immer in die Benutzer-Site-Pakete.

+1

  • Wenn --global übergeben wird, installieren wir immer auf der globalen Site
  • Pakete.

Globale _Vendor_-Pakete == +1, globale Site-Pakete == -1.

  • Wenn keines der beiden bestanden wird, implementieren wir eine Fallback-Methode, die:

    1. Erkennt, ob wir uns in einer virtuellen Umgebung befinden, und verhält sich dann so, als ob

      --global wurde übergeben.

+1, obwohl ich wiederhole, dass dieses Verzeichnis in einem venv benannt ist
/lib/pythonX.Y/site-packages

  1. Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob
    --global wurde übergeben.

Hm, bei diesem hier bin ich mir nicht sicher.

  1. Schaut auf default-install und verwendet --user oder falls vorhanden
    -global darauf basierend.

+1

  1. Erkennt, ob der effektive Benutzer keine Schreibberechtigungen für global hat
    Site-Pakete, und wenn sie sich nicht so verhalten, als ob --user übergeben wurde.

+1

  1. Wenn alle anderen Erkennungsmethoden fehlgeschlagen sind, verhalten Sie sich schließlich so, als ob --global
    war vorbei.

Auch nicht sicher.

Dies würde bedeuten, dass es keine Abschreibungsfrist gibt und dass die Erwartung in der liegt
Fehlen von --user oder --global werden wir versuchen, die beste Vermutung zu treffen
auf die Fähigkeiten des Python, in dem wir laufen, der effektive Benutzer und
jede konfigurierte Standardinstallationsmethode.

Klingt nach einem vernünftigen Ziel.

Um es klar zu sagen, wenn ich von "globalen Site-Paketen" spreche, meine ich in erster Linie "was auch immer distutils uns sagt, dass wir Dinge global installieren sollen". Da Python selbst keine Unterscheidung zwischen "Vendor Local" und "Site Local" hat, wird dies dasselbe Verzeichnis auf jedem Downstream sein, der sein Python nicht patcht. Unter Debian wird es jedoch tatsächlich ein dist-packages -Verzeichnis sein und "global" bedeutet eigentlich "site local". Das ist jedoch nichts, wofür pip etwas Besonderes tun muss, um es zu unterstützen, da dies von Debuntus Patches für Python erledigt wird.

Mit anderen Worten, pip wird auf Debuntu bereits in /usr/local/../dist-packages/ installiert, da Debuntu distutils gepatcht hat, um diese Unterscheidung zu unterstützen. Das einzige Mal, dass pip mit /usr/../dist-packages/ herumspielen würde, ohne dass der Benutzer irgendein Flag übergibt, ist, dass pip Dateien von dort deinstallieren würde (weil pip dieses Verzeichnis nicht als etwas Besonderes ansieht, es sieht es nur als eine Sache an auf sys.path ). Debian hat pip gepatcht, um diese Deinstallation von dort aus zu verhindern, und ich denke, echte Unterstützung dafür hängt davon ab, dass echte Unterstützung für "Vendor Local"-Site-Pakete in Python Upstream erhalten wird.

Wir möchten wahrscheinlich eine Art Warnung, wenn wir in --user installieren und ~/.local/bin nicht im $PATH ist

Wie zerbrechlich ist diese Warnung wahrscheinlich? Würde es in einen absoluten Pfad konvertieren? Würde es bei Dateisystemen ohne Berücksichtigung der Groß-/Kleinschreibung Groß-/Kleinschreibung beachten? Würde es unter Windows und / als gleichwertig behandelt? Was ist mit Symlinks?

Wenn Sie ein Paket installieren, das keine Skripte installiert, ist die Warnung ohnehin irrelevant.

Ich persönlich denke, dass eine Abmahnung wahrscheinlich mehr schaden als nützen wird.

Wir möchten wahrscheinlich eine Art Warnung, wenn wir in --user installieren und
~/.local/bin ist nicht auf $PATH .

+1, vielleicht mit einer Konfigurationsoption, um die Warnung zu unterdrücken?

Wir könnten einfach eine Python-Warnung verwenden, damit die Leute einfach schweigen können
es mit den eingebauten Python-Warnungen. Wenn wir das Bedürfnis verspüren, es zum Schweigen zu bringen
alle.

Ab Pip 6.0 haben wir maschinenspezifische Konfigurationsdateien, die sich in /etc/ befinden
Diese sind jedoch nicht spezifisch für die ausgeführte Version von Python
Pip. Ich denke, das ist ein gutes Feature, wenn auch etwas getrennt (und
könnte auch Hand in Hand gehen mit der Lösung des Script-Clobbering-Dings).

Ich würde eine Suchreihenfolge vorschlagen wie:

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

zuerst(?) in /etc/xdg/pip gerootet dann /etc, wobei XY natürlich das ist
Major.Minor-Versionsnummer. Wer zuerst gefunden wird, gewinnt.

Teilen Sie dies in # 2417 auf, da ich glaube, dass es nur tangential damit zusammenhängt
Diskussion.

Eine große offene Frage sehe ich noch: Langfristig, was wollen wir wann passieren
jemand tut sudo pip install foo oder besser gesagt, wenn jemand die Erlaubnis dazu hat
in das Verzeichnis site-packages schreiben?

Bitte beachten Sie, dass es nicht nur ein "site-packages"-Verzeichnis gibt. Zum Beispiel,
Auf Debian/Ubuntu wollen wir nicht, dass sudo pip install _überhaupt_ installiert wird
/usr/lib, aber nur /usr/local/lib. Und vergiss nicht, es sind dist-Pakete hier
keine Site-Pakete (außer in ~/.local aus $gründen).

Das ist wirklich ein wichtiger Punkt, der manchmal (auch von mir) vergessen wird.
Donald beschreibt es am besten, wenn er sagt, dass es ein Site-Local-Verzeichnis und ein
anbieterlokales Verzeichnis. Unter Debian ist site-local
/usr/lib/pythonX.Y/dist-packages und kein Pip-Befehl sollte das jemals berühren,
Vendor-Local hingegen ist /usr/local/lib/pythonX.Y/dist-packages und es ist a
dokumentierter und beliebter Anwendungsfall für einige Systemadministratoren zur Pip-Installation
in dieses Verzeichnis.

Was ich also vorschlagen würde, da wir bereits den Konfigurationsdateipfad heruntergefahren sind, ist zu
diese konfigurierbar machen, zB

  • globales_Installationsverzeichnis
  • global_install_as_sudo (wahr/falsch)

pip kontrolliert diese nicht wirklich (ich meine, offensichtlich auf dem hohen Niveau, das es tut
weil es derjenige ist, der Dateien herumbewegt), stammen sie aus distutils/sysconfig.

Ich denke, dass pip wahrscheinlich niemals ein lokales Verzeichnis des Anbieters berühren sollte, es sei denn
Es wurde eine Art Flag wie --vendor angegeben, das es den Anbietern ermöglichen würde, es zu verwenden
Pip in ihrer Build-Kette. Dieses Konzept existiert außerhalb von debuntu nicht wirklich
gerade jetzt und ihre Patches handhaben das bereits, also denke ich nicht, dass es super ist
relevant für diese Diskussion, außer um das zu bemerken, wenn ich es sage
"globale Site-Pakete" Ich meinte /usr/local/.../dist-packages auf Debubuntu
und die "site-local"-Pakete irgendwann, wenn Python das Debuntu akzeptiert
System vorgelagert.

  1. Installieren Sie in --global . Dies ist die abwärtskompatibelste Option
    und stellt wahrscheinlich dar, was Benutzer erwarten, wenn sie das eingeben. Allerdings hat es
    der Nachteil, dass es (leise) mit dem globalen Python durcheinander kommt, was auf vielen
    Systeme können defekte Systeme verursachen.

Mit der obigen Konfigurierbarkeit wäre dies vollständig kompatibel mit Debian.
Debian-Superuser erwarten, dass sudo pip install hineingehen
/usr/local/lib/pythonX.Y/dist-packages. Ich würde nicht sagen, dass es "durcheinander bringt
system", weil es den Paketmanager nicht unterbricht und obwohl es das kann
vom System installierte Pakete außer Kraft setzen (die sich in
/usr/lib/pythonX.Y/dist-packages), tut dies auf eine definierte, dokumentierte Weise.

Ja, "Durcheinander mit dem System" kann zu hart sein. Meistens meine ich das
sudo pip install foo kann Dinge kaputt machen, wenn das System von foo abhängt und
Sie installieren eine inkompatible Version von Dingen. Derselbe Fall gilt jedoch
true für im Grunde alles , was Sie in `/usr/local`` installieren.

  • Wenn --global übergeben wird, installieren wir immer auf der globalen Site
  • Pakete.

Globale _Vendor_-Pakete == +1, globale Site-Pakete == -1.

Du meinst das andersherum oder?

  • Wenn keines der beiden bestanden wird, implementieren wir eine Fallback-Methode, die:

    1. Erkennt, ob wir uns in einer virtuellen Umgebung befinden, und verhält sich dann so, als ob

      --global wurde übergeben.

+1, obwohl ich wiederhole, dass dieses Verzeichnis in einem venv benannt ist
/lib/pythonX.Y/site-packages

Ja, wieder fragen wir Python nur, wo sich dieses Verzeichnis befindet, wir berechnen es nicht
uns selbst, also ist "wo dieses Verzeichnis ist" eine Sache von venv/virtualenv.

  1. Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob
    --global wurde übergeben.

Hm, bei diesem hier bin ich mir nicht sicher.

Ich glaube nicht, dass es keinen Ausweg gibt, wenn Benutzer-Site-Pakete deaktiviert sind
glaube nicht, dass wir dort installieren sollten, weil wir es nicht wissen können
wenn diese Deaktivierung bedeutet, dass es keine Benutzer-Site-Pakete gibt, oder warum. Wir können nur
gehe mal davon aus das es keine gibt.

  1. Wenn alle anderen Erkennungsmethoden fehlgeschlagen sind, verhalten Sie sich schließlich so, als ob --global
    war vorbei.

Auch nicht sicher.

Dies läuft im Wesentlichen darauf hinaus:

Wenn wir keinen Grund gefunden haben, sollten wir --user verwenden, wie ein --user-Flag, oder
keine Berechtigung zum Schreiben in das Verzeichnis haben, dann verwenden Sie es nicht. Dies
ist, was sudo pip install foo ohne ein --global -Flag halten wird
Arbeiten. Dies bedeutet auch, dass dies die wichtigste Regel ist, um nicht zu brechen
funktionierende Software, die erwartet, dass sich sudo pip install foo so verhält.

Wir möchten wahrscheinlich eine Art Warnung, wenn wir in --user installieren und ~/.local/bin nicht im $PATH ist

Wie zerbrechlich ist diese Warnung wahrscheinlich? Würde es in einen absoluten Pfad konvertieren? Würde es bei Dateisystemen ohne Berücksichtigung der Groß-/Kleinschreibung Groß-/Kleinschreibung beachten? Würde es unter Windows und / als gleichwertig behandelt? Was ist mit Symlinks?

Wenn Sie ein Paket installieren, das keine Skripte installiert, ist die Warnung ohnehin irrelevant.

Ich persönlich denke, dass eine Abmahnung wahrscheinlich mehr schaden als nützen wird.

Nun, wir könnten es als (plattformübergreifendes Äquivalent von) implementieren:

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

So etwas sollte meiner Meinung nach mit Symlinks, Pfadtrennzeichen und dergleichen umgehen. Teufel im Detail und vielleicht können wir es nicht genau genug hinbekommen, um die verschiedenen plattformübergreifenden Eckfälle abzudecken.

Ich stimme zu, dass die Warnung irrelevant ist, wenn keine Skripte installiert werden, und ich wollte sagen, dass wir uns nur mit der Warnung beschäftigen würden, wenn wir Skripte installieren.

Die Grundidee ist, dass ich nicht möchte, dass jemand etwas wie pip install [--user] foo tut, wo der --user implizit ist, und dann foo macht und einen "Befehl nicht gefunden" ohne Anleitung bekommt warum es möglicherweise nicht gefunden wird. Zumindest eine Warnung wird ihnen sagen, dass sie Dinge zum PATH hinzufügen müssen. Es kann auch dazu beitragen, Benutzer unter Windows aufzufordern, ihr Benutzerverzeichnis manuell zu ihrem PATH hinzuzufügen (oder ein Skript auszuführen, um dies zu tun), was die Notwendigkeit der activate -Skripte verringern könnte, auf die Steve hingewiesen hat. Obwohl ich denke, dass dies immer noch bedeuten würde, dass Systemwerte Vorrang vor Benutzerwerten haben, könnte dies immer noch verwirrend sein, da die Reihenfolge von PATH und sys.path immer noch umgekehrt wäre.

Doh. Ich habe vergessen, dass realpath den Pfad kanonisiert hat. Ja, das funktioniert natürlich gut genug.

Was mich stört, ist, dass _wenn_ der Test fälschlicherweise ein Problem erkennt, der Benutzer eine ärgerliche und falsche Warnung erhält, ohne dass er es vermeiden kann, außer sein System zu ändern, um einen Fehler von pip zu umgehen. Da der von Ihnen vorgeschlagene Test jedoch wahrscheinlich robust genug ist und wir die Überprüfung nur durchführen, wenn wir Skripts installieren, ist das Problem wahrscheinlich selten genug, um ignoriert zu werden.

Okay, ich denke, wir haben hier eine breite Übereinstimmung. Ich denke, der nächste Schritt ist, einen Patch zu bekommen. Ich werde weitermachen und versuchen, heute Abend oder morgen etwas aufzutreiben.

Am 10. Februar 2015 um 12:14 Uhr schrieb Donald Stufft:

Die Grundidee ist, dass ich nicht möchte, dass jemand etwas wie pip install [--user] foo macht, wo --user implizit ist, und dann foo und macht
erhalten Sie einen "Befehl nicht gefunden" ohne Anleitung, warum dies möglicherweise nicht der Fall ist
gefunden.

Debian und vielleicht andere Linuxe haben tatsächlich ein Befehl-nicht-gefunden-Paket
die den Benutzer auffordert, ein Paket zu installieren, wenn sie einen Befehl aufrufen, der
ist nicht installiert.

% Inkscape
Das Programm 'inkscape' ist derzeit nicht installiert. Sie können es installieren, indem Sie Folgendes eingeben:
sudo apt-get install inkscape

Vielleicht könnten wir uns da für unterstützende Plattformen einklinken.

Am 10. Februar 2015 um 12:06 Uhr schrieb Donald Stufft:

  • Wenn --global übergeben wird, installieren wir immer auf der globalen Site
  • Pakete.

Globale _Vendor_-Pakete == +1, globale Site-Pakete == -1.

Du meinst das andersherum oder?

Ich könnte meine Terminologie verwechseln, also werde ich explizit sein:

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

Aber wie Sie bereits sagten, ist dies nichts, worüber Pip sich wirklich Sorgen machen muss
ungefähr, da es von distutils geerbt wurde und Debuntus distutils gepatcht ist
das Richtige zu tun.

  1. Erkennt, ob Benutzer-Site-Pakete deaktiviert sind, und verhält sich in diesem Fall so, als ob
    --global wurde übergeben.

Hm, bei diesem hier bin ich mir nicht sicher.

Ich glaube nicht, dass es keinen Ausweg gibt, wenn Benutzer-Site-Pakete deaktiviert sind
glaube nicht, dass wir dort installieren sollten, weil wir es nicht wissen können
wenn diese Deaktivierung bedeutet, dass es keine Benutzer-Site-Pakete gibt, oder warum. Wir können nur
gehe mal davon aus das es keine gibt.

Oh, jetzt verstehe ich, was du meinst. Ich denke, das macht Sinn. Meine Sorge ist, dass es
kann schwieriger vorherzusagen sein, was Pip tatsächlich tun wird, aber wie ich
sagen wir, ich wäre glücklich mit einem --dry-run-Flag, damit Pip eindeutig _sagen_ kann
Sie, was es tun wird.

  1. Wenn alle anderen Erkennungsmethoden fehlgeschlagen sind, verhalten Sie sich schließlich so, als ob --global
    war vorbei.

Auch nicht sicher.

Dies läuft im Wesentlichen darauf hinaus:

Wenn wir keinen Grund gefunden haben, sollten wir --user verwenden, wie ein --user-Flag, oder
keine Berechtigung zum Schreiben in das Verzeichnis haben, dann verwenden Sie es nicht. Dies
ist, was sudo pip install foo ohne ein --global -Flag halten wird
Arbeiten. Dies bedeutet auch, dass dies die wichtigste Regel ist, um nicht zu brechen
funktionierende Software, die erwartet, dass sich sudo pip install foo so verhält.

Ich verstehe. Ich denke, das ist in Ordnung, denn der wichtigste Anti-Use-Fall, den wir vermeiden wollen, ist:

normal_user$ pip installiere foo
HEY SIE HABEN KEINE BERECHTIGUNGEN
normal_user$ sudo pip install foo
HEY, SIE HABEN NUR IHR SYSTEM VERBOTEN

und die Regel "keine Berechtigung zum Schreiben in das Verzeichnis zu haben impliziert --user".
kümmert sich darum.

Oh ja, ich habe Befehl-nicht-gefunden vergessen. Könnte nützlich sein. Kennen Sie übrigens die richtige Stelle, um vorzuschlagen, dass devubtu standardmäßig den Benutzer local bin auf dem Pfad hat?

Am 10. Februar 2015 um 16:05 Uhr schrieb Barry Warsaw [email protected] :

Am 10. Februar 2015 um 12:14 Uhr schrieb Donald Stufft:

Die Grundidee ist, dass ich nicht möchte, dass jemand etwas wie pip install [--user] foo macht, wo --user implizit ist, und dann foo und macht
erhalten Sie einen "Befehl nicht gefunden" ohne Anleitung, warum dies möglicherweise nicht der Fall ist
gefunden.

Debian und vielleicht andere Linuxe haben tatsächlich ein Befehl-nicht-gefunden-Paket
die den Benutzer auffordert, ein Paket zu installieren, wenn sie einen Befehl aufrufen, der
ist nicht installiert.

% Inkscape
Das Programm 'inkscape' ist derzeit nicht installiert. Sie können es installieren, indem Sie Folgendes eingeben:
sudo apt-get install inkscape

Vielleicht könnten wir uns da für unterstützende Plattformen einklinken.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

Am 10. Februar 2015 um 13:17 Uhr schrieb Donald Stufft:

Oh ja, ich habe Befehl-nicht-gefunden vergessen. Könnte nützlich sein. Du übrigens
Kennen Sie die richtige Stelle, um vorzuschlagen, dass devubtu den lokalen Benutzer auf dem Bin hat
Pfad standardmäßig?

Nicht definitiv, aber vielleicht die Pakete adduser oder passwd? Ersteres besitzt
/usr/sbin/adduser und letzterer besitzt /usr/bin/useradd.

Ich bin mir nicht sicher, ob das hilft, aber…

  • ~/.local/bin ist nicht im $PATH vieler Leute, kann man dagegen etwas tun?

Einige andere Projekte verwenden /etc/profiled.d/ zum Hinzufügen von Verzeichnissen zu $PATH. Zumindest auf Antergos sehe ich Folgendes (sofern ich nicht falsch verstehe, was diese tun) 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

Als zufälliger Pip-Benutzer möchte ich nur _danke_ sagen, dass Sie an Problemen mit der Benutzererfahrung wie dieser und den anderen arbeiten, die im Meilenstein „ Verbessern unserer Benutzererfahrung “ erfasst wurden. Gibt es einen Ort, an dem ich mich finanziell an diesen Bemühungen beteiligen kann?

Abgesehen davon verwende ich Homebrew und habe es immer geschätzt, dass ich nur brew install something konnte und es ohne viel Aufhebens um Berechtigungen funktionieren würde.

Nachdem ich verstanden hatte, warum die Installation mit Homebrew niemals sudo erforderte, versuchte ich, es mir zur Gewohnheit zu machen, pip install --user something zu tun, aber ironischerweise deaktiviert Homebrew dies aufgrund eines gemeldeten Fehlers in distutils.

Angesichts der Popularität von Homebrew unter OS X möchten Sie vielleicht alle diese angebliche Inkompatibilität von Homebrew und pip install --user .

Wie auch immer, +1 von mir, um --user zum Standard zu machen.

Ein schnelles Follow-up. Didier hat eine Änderung an Ubuntus Pip in Vivid hochgeladen, die --user als Standard festlegt. Ich habe es meistens auch zugelassen, aber jetzt denke ich, dass es ein Fehler war, und ich beabsichtige, das für schlau rückgängig zu machen (aber wahrscheinlich wird SRU keine Änderung für lebendig). Siehe https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1460203 für Details und Begründung.

+1 dafür, dass Upstream das Timing dieser Änderung bestimmen kann, da die Unterscheidung zwischen Benutzer und System bereits verwirrend genug ist, ohne dass Plattformunterschiede ins Spiel kommen.

Das heißt, es kann für die Linux-Distributionen sinnvoll sein, die Standardeinstellung auf --user umzustellen, sobald --global support im Upstream-Pip (Pip 8?) landet, da globale Installationen unter Linux durchgeführt werden, anstatt pro Benutzer oder per-venv installiert, ist als schlechte Idee mit möglicherweise unvorhersehbaren Nebenwirkungen bekannt.

Ich habe es @warsaw privat gesagt, aber ich werde es auch hier sagen:

Ich denke, dass diese Änderung wichtig ist, und ich plane, auf meinen Pull-Request zurückzukommen, um ihn abzuschließen. Ich bin jedoch eine Person, die sich über mehrere Projekte erstreckt, und im Moment ist Warehouse für mich wichtiger als diese Änderung, da das PyPI-Legacy immer mühsamer zu betreiben ist und ich das Gefühl habe, dass wir das so schnell wie möglich ersetzen müssen. Daher konzentriert sich meine Zeit bei pip nicht darauf, selbst viele Änderungen vorzunehmen, sondern darauf, durch Änderungen anderer Mitwirkender sowie durch alle Dinge des Veröffentlichungsprozesses zu führen.

Abgesehen davon, wenn sich jemand wirklich darum kümmert, dass dieses Feature früher oder später landet, kann er meine Arbeit aufnehmen und fertigstellen, und ich werde sie gerne überprüfen (und hoffentlich zusammenführen). Ich freue mich, darüber mit jedem zu sprechen, der es tun möchte, und eine Anleitung für die Änderung zu geben. Andernfalls wird es warten, bis ich die Punkte erledigt habe, die für mich dringender sind.

Vielleicht lohnt es sich, an dieser Stelle zu wiederholen:

Wenn wir uns am Ende gegen „default to --user“ entscheiden, sollten wir die weniger störenden Alternativen in Betracht ziehen

  1. Fallback auf --user (wenn die Installation aufgrund von Berechtigungsfehlern fehlschlägt)
  2. (Wenn die Installation aufgrund von Berechtigungsfehlern fehlschlägt), ermutigen Sie den Benutzer (in großen freundlichen Buchstaben), es mit --user zu versuchen

FWIW, jetzt, da das Windows-Installationsprogramm für Python 3.5 nachdrücklich zu einer Installation pro Benutzer ermutigt, bin ich nicht so besorgt über diese Änderung, die in pip auftritt. Es wäre wahrscheinlich eine bessere Konfigurationsoption für Distributionen (mit der --global -Überschreibung) als eine neue Standardeinstellung oder ein Fallback.

Ich wollte dieser Ausgabe nur +1 geben und danke sagen, dass Sie daran gearbeitet haben! Wir veranstalten derzeit eine wissenschaftliche Python-Sommerschule und hatten viele Leute sudo pip install , als sie auf Berechtigungsprobleme stießen.

FWIW Ich bin dafür, standardmäßig auf --user zu setzen oder auf --user zurückzugreifen, wenn die Installation aufgrund von Berechtigungsfehlern fehlschlägt. In diesem Fall würde ich ihnen lieber Anweisungen geben, wie sie das, was sie getan haben, rückgängig machen können (z. B. We installed to your user directory. If you don't want this, then 'pip uninstall my_package' ), anstatt zu scheitern und ihnen zu sagen, wie sie es noch einmal versuchen sollen.

Ich sehe viele Fehlerberichte auf Mock aufgrund von --user - zumindest auf Ubuntu, wo der Platz von --user auf dem Pfad nach dist-packages ist, und daher wird das installierte Pip nicht wirklich verwendet, für eine allgemeine Abhängigkeit (wie sechs), die sich in dist-Paketen befindet.

Sie haben es _nach_ dist-packages geschrieben? Das ist eine defekte Installation IMO.

Richtig, Benutzerinstallationen sollten vor site(/dist)-Paketen erfolgen, und dann sollten Systemskripte und Dienstprogramme mit -I (oder -Es in Python 2) ausgeführt werden.

Ja, ich stimme zu :). Es mag in lebhafter Weise behoben werden, aber ich habe definitiv Berichte gesehen, wo die Dinge von der völlig falschen Stelle kommen.

Ich habe gerade das System-PIP verwendet, um Setuptools auf meiner Vivid-Maschine zu installieren, um zu experimentieren.

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

Dieser ist also vernünftig. Aber verwirrenderweise wurde dies anschaulich eingeführt – so IDK. Ich werde sehen, ob ich irgendwann einen Reproduktioner ausgraben kann (zum Ablegen im Ubuntu BTS)

Paging @warschau

Benutzer-Site-Pakete können durch die bösen .pth-Dateien von setuptools nach globalen Site-Paketen neu angeordnet werden. Dies war ein wiederkehrendes Problem für mich, bis ich lernte, setup.py niemals direkt zu verwenden - ich installierte etwas und plötzlich verwendete ich ältere Versionen aller möglichen anderen Dinge. Nach ein paar Mal schrieb ich ein aggressives Tool , um mein System zu entwirren.

Ich denke, zumindest sollte pip vorerst nur eine freundliche Nachricht ausgeben, in der der Benutzer aufgefordert wird, --user auszuführen, wenn der Befehl fehlschlägt. Während es seine Vorteile hat, es auf die Standardeinstellung umzustellen, sollte das Drucken einer besseren Nachricht nicht zu schwer sein.

Es ist eine nette "schnelle Lösung" für das Problem, bis wir tatsächlich dazu übergehen, standardmäßig auf --user zu setzen.

Ein --global, --system oder --no-user ist ebenfalls erforderlich, falls der Benutzermodus in /etc/pip.conf eingestellt ist. Soweit ich das beurteilen kann, gibt es für Benutzer keine einfache Möglichkeit, dies zu überschreiben.

Es ist eine nette "schnelle Lösung" für das Problem

Spätes Update: #4233 hat dies getan.

Leute (insbesondere Neueinsteiger), die kein Windows verwenden, sollten wirklich auf https://github.com/pyenv/pyenv verwiesen werden, wenn sie eine gute Erfahrung machen wollen. PEP 370 macht für mich heute nicht viel Sinn, zumal ~/.local XDG_DATA_HOME ist.

Ich denke, ich werde nicht der einzige sein, der sich gegen dieses Verhalten entscheidet, falls/wenn es dazu kommt. Hoffentlich verläuft der Übergang reibungslos und ich muss die Funktionsweise meines Systems nicht ändern und zusätzliche CLI-Flags übergeben, da ich mit pyenv recht zufrieden bin. Natürlich weiß ich nicht, wie gut pyenv mit Windows funktioniert, aber das Bash-Subsystem könnte dort helfen ...

@jcrben pyenv macht einige Annahmen darüber, wie Leute Python verwenden (und insbesondere, wie sie ihre Python-Binärdateien erwerben), was bedeutet, dass es sehr gut für Leute funktioniert, für die diese Annahmen gültig sind, aber ist nicht universell genug, um die Standardempfehlung zu sein (in dieser Hinsicht ist es ähnlich wie conda ).

Der --user -Standardwert auf der pip -Ebene hat keine Auswirkungen auf ordnungsgemäß konfigurierte virtuelle Python-Umgebungen, daher wirkt sich diese Änderung auf Umgebungsmanager von Drittanbietern wie conda und pyenv aus pip und andere Tools erkennen (d. h. entweder so, wie virtualenv ihn meldet, oder wie venv der Standardbibliothek).

Verwandter Vorschlag: https://github.com/pypa/pip/issues/1056#issuecomment -218130183.

~ Wurde in Betracht gezogen, dem Benutzer zu erlauben, das Verzeichnis anzupassen (wahrscheinlich durch eine env-Variable), um eine direkte Installation in ~/.local zu vermeiden? Ich würde sie wahrscheinlich lieber in ~/.local/pip oder so verschachteln - soweit es mich betrifft, hat Python kein besonderes Recht auf die oberste Ebene dieses gemeinsam genutzten Bereichs. ~ Auf 9.0.1 scheint es Dinge unter ~/.local/lib/python<version> zu verschachteln und ausführbare Dateien zu ~/.local/bin hinzuzufügen, was meiner Meinung nach in Ordnung ist ...

@jcrben Ja, der Zielspeicherort ist eigentlich das Benutzer-Site-Verzeichnis von Python, das das Namensschema für das System-Site-Packages-Verzeichnis widerspiegelt: https://docs.python.org/3/library/site.html#site.USER_SITE

Dies ist bereits auf Interpreterebene über die Umgebungsvariable PYTHONUSERBASE konfigurierbar: https://docs.python.org/3/using/cmdline.html#envvar -PYTHONUSERBASE

Für Interessierte habe ich gerade https://github.com/ofek/hatch veröffentlicht, das die Paketbefehle install , uninstall und update enthält, die standardmäßig dieses Verhalten aufweisen. Für Systemänderungen können Benutzer die Option -g/--global verwenden, ähnlich wie bei https://github.com/npm/npm.

Angesichts des jüngsten Problems mit Malware-infizierten Paketen auf PyPI denke ich, dass es im besten Interesse von pip ist, alles zu tun, um die Verwendung von sudo pip install ... zu verhindern, insbesondere unter Berücksichtigung der Tatsache, dass die Setup-Skripte bei der Installation beliebigen Code ausführen können. Das Installieren infizierter Pakete als Benutzer ist schon schlimm genug, aber es ist viel schlimmer, wenn sie als Root installiert werden.

Die standardmäßige Benutzerinstallation bedeutet, dass weniger Leute ihrem pip-Befehl sudo voranstellen, was bedeutet, dass versehentlich installierte Malware weniger tun kann.

Als konkreten nächsten Schritt habe ich ein separates Problem für das Hinzufügen eines --global -Flags ausgebrochen: https://github.com/pypa/pip/issues/4865

Dies ist mit ziemlicher Sicherheit eine schlechte Idee in virtualenv- oder Conda-Umgebungen. Was auch immer in .local installiert wird, wenn eine Umgebung aktiv ist, könnte leicht eine andere Umgebung beschädigen. Was denkt man also in diesen Fällen?

cc @msarahan @kalefranz

Dieses Problem tritt nicht auf, wenn Sie sich in einer aktiven virtuellen Umgebung befinden – es tritt nur auf, wenn keine aktive Umgebung erkannt wird und keine der Zieldefinitionsoptionen ( --prefix , --root usw.) angegeben wurde auf der Kommandozeile.

Wie wird dies ermittelt?

Wir haben darüber nachgedacht, standardmäßig ~/.local auf sys.path für Python in Conda-Umgebungen zu deaktivieren, was per Definition jede von Conda installierte Python ist. Es ist jedoch schwierig. So oder so könnten wir am Ende die Erwartungen einer Gruppe von Benutzern verletzen. Diskussion unter https://github.com/conda/conda/issues/7173

Konnte pip kein Argument aus Umgebungsvariablen laden, die mit PIP_ beginnen? Funktioniert das für --user ? Wie wäre der vollständige Variablenname?

Das wäre PIP_USER .

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

PIP_USER=yes um genau zu sein, danke! Die Verwendung von Umgebungsvariablen ist für die CI-Nutzung viel einfacher, da Sie sie nur einmal definieren müssen und sie bei jedem Aufruf der Befehle verwendet werden.

Ich musste eine wirklich hässliche Logik für Travis machen, wo anscheinend einige Stufen als normaler Benutzer ohne virtualemv und einige innerhalb einer virtuellen Umgebung ausgeführt werden, und Sie haben keine Ahnung, welche es sein würde.

innerhalb von virtualenv ist wahrscheinlich, dass —user fehlschlägt, wenn Sie keine Site-Pakete verwendet haben (was andere Probleme verursacht).

Dies bedeutete, dass ich virtualenv in bash erkennen und vermeiden musste, den -user hinzuzufügen, da sonst die Ausführung fehlschlägt.

Das ist hässlich und hat dazu geführt, dass ich viel Zeit mit dem Debuggen verschwendet habe. Ich bin sicher, dass andere dasselbe erleben werden.

Ich denke, wir brauchen eine Option, die einen Fallback bezüglich der Installation aktiviert: wie beim Benutzer installieren, wenn Sie können, und auf das System zurückfallen.

pip sollte nur fehlschlagen, wenn es keinen Platz zum Installieren eines Pakets findet.

Irgendeine Bewegung dazu?

Ich habe es nicht erwähnt gesehen, aber vielleicht sollte sich Pip beschweren, wenn --user übergeben wird, wenn es unter sudo ausgeführt wird.

Diese ungelösten Probleme führen Programmierer weg von Pip und sogar Python und zwingen sie, andere Pakete oder sogar andere Programmiersprachen wie Javascript und npm mit weniger Problemen wie diesem zu verwenden. Für einen Anfänger, der Python verwenden möchte, sind diese zusätzlichen notwendigen Optionen frustrierend.

Warum sollte --user Standard sein? Kann es nicht explizit angegeben werden? Ich kann pip --target nicht ausführen, weil es sich beschwert, dass es nicht in Verbindung mit user verwendet werden kann. Irgendeine Idee, wie man es vermeiden kann?

@dmikov : Es ist nicht die Standardeinstellung. Es sei denn, Sie verwenden eine defekte Debian/Ubuntu-Version . In diesem Fall können Sie umgehen, dass --user automatisch festgelegt wird, indem Sie Folgendes verwenden: PIP_USER=0 pip install -t ... . Oder noch besser, installieren Sie eine offizielle Version und verwenden Sie diese.

Ich habe nachts davon geträumt, dass die --user -Option zur Standardeinstellung wird (kein Scherz), gibt es eine Chance, dass meine Träume bald wahr werden?

Ich brauche Hilfe bei der Installation von Pygame, es sagt immer wieder ungültige Syntax

ich benutzte
python3 -m pip install -U pygame --user
ist das falsch was soll ich tun?

@flamedro56 : Anstatt ein zufälliges Problem zu kommentieren, öffnen Sie bitte ein neues und geben Sie weitere Informationen an: Python-Version, Pip-Version, Betriebssystem, die Befehlsausgabe ...

Installer reCAPTCHA

Wie wäre es mit einer neuen Konfigurationsoption default=system,user? Es wäre explizit genug, dass niemand denken würde, dass es "immer Benutzer, sogar in virtualenv" bedeutet. Es würde einen eleganten Migrationspfad ermöglichen.

Siehe #4575.

Sieht so aus, als ob Manjaro versucht, --user als Standard festzulegen.

Gibt es etwas Neues von Upstream zu diesem Problem?

@Tids : "filesystem-2018.9-3 fügt standardmäßig $HOME/.local/bin zu Ihrem $PATH hinzu." ist das entscheidende Extrastück, das Manjaro richtig macht.

Debian kombiniert „default to --user“ auf Python-Ebene mit „$HOME/.local/bin is not on your $PATH by default“ auf Benutzerkontoebene, und das ist die Kombination, die die Dinge kaputt macht.

In #7002 habe ich versucht, Pip dazu zu bringen, standardmäßig eine Benutzerinstallation durchzuführen, wenn das globale Site-Packages-Verzeichnis nicht beschreibbar ist und Benutzer-Site-Pakete aktiviert sind. Dies sollte weitgehend vermeiden, eine Benutzerinstallation durchzuführen, wenn Sie in eine Umgebung installieren wollten, solange Sie die Berechtigung zum Ändern der Umgebung haben.

Ich suche zuerst eine Diskussion über die Idee - lassen Sie uns nicht in die Prüfung der Implementierung einsteigen, bevor wir darüber nachgedacht haben, ob es überhaupt Sinn macht, das Ding zu machen.

Es ist erwähnenswert, dass das Mischen von Benutzerinstallationen und Nichtbenutzerinstallationen (von pip selbst) mit Problemen behaftet ist - siehe kürzlich #7209 als ein Beispiel.

Obwohl es nicht direkt mit diesem Problem zusammenhängt (und tatsächlich, wenn wir standardmäßig Benutzer verwenden, kann das die Situation etwas erleichtern), betont es die Notwendigkeit, sorgfältig darüber nachzudenken, wie wir mit einem Übergang zu --user als Standard umgehen.

(Ich füge diesen Kommentar hauptsächlich hier hinzu, damit er irgendwo aufgezeichnet wird - es ist meistens überhaupt kein Pip-Problem, sondern eher eine Komplikation der Funktionsweise des USER_SITE-Verzeichnisses von Python im Allgemeinen, das von Benutzern, die mit --user installieren, nicht ausreichend verstanden wird

Es sieht so aus, als ob das Problem darin besteht, dass PATH (zum Suchen von Befehlen) und sys.path (zum Suchen von Python-Importen) entgegengesetzte Prioritäten haben, sodass das Launcher-Skript von einer Installation versucht, das Paket aus der zu laden andere. Es ist vermutlich nicht spezifisch für pip - es könnte jedes Paket betreffen, das ein Skript installiert.

Ich bin mir nicht sicher, was wir dagegen tun können, aber ich stimme zu, dass es sich lohnt, darüber nachzudenken.

Ja, das ist die wichtigste "Komplikation von USER_SITE", die ich im Sinn hatte. Meiner Meinung nach ist es die effektivste Lösung, Wrapper-Skripte abzulehnen und nur python -m pip zu unterstützen. (Ich bin nicht per se gegen Wrapper, aber die Probleme, die wir mit ihnen sehen, sind normalerweise Leute, die versehentlich den falschen Wrapper ausführen, daher ist das Beheben von Problemen mit Wrapper-Skripten normalerweise kein Pip-Problem als solches, sondern eher eine „Diagnose und Behebung einer Fehlkonfiguration der Benutzerumgebung " Ausgabe)

Sie meinen, das Wrapper-Skript pip abzulehnen oder Wrapper-Skripte abzulehnen, da sie von pip installiert werden können?

Bei letzterem bin ich sicherlich -1 - die Möglichkeit, Befehle zu installieren, ist sehr nützlich, auch wenn es Probleme verursacht.

Es könnte sinnvoller sein, pip zugunsten von python -m pip abzulehnen. Wenn pip in der Python-Umgebung installiert wird, in der es ausgeführt wird, ist es sinnvoll, klar zu sein, welche das ist. Aber es wäre immer noch ein Komfortverlust und ein großer Bruch mit dem, woran die Menschen gewöhnt sind.

Ich meinte speziell die Wrapper-Skripte für Pip selbst. Einverstanden, dass es ein Verlust an Bequemlichkeit ist, und ich wäre nicht dagegen, sie in irgendeiner Form beizubehalten (#3164 schlägt vor, ein neues pip-cli -Projekt zu haben, das nur die Wrapper liefert), aber der entscheidende Punkt wäre für python -m pip als unterstütztes Mittel zum Ausführen von Pip.

Der Aufruf des Pip-Wrapper-Skripts konnte keine Warnung anzeigen, wenn das aktuelle python (im PATH oder was auch immer mit python -m pip verwendet werden würde) nicht das python ist, das von pip verwendet wird python -m pip delegieren, wenn es so aufgerufen wird?

In ähnlicher Weise warnt pipenv, wenn sich der Benutzer bereits in einer virtuellen Umgebung befindet, und verwendet in diesem Fall diese virtuelle Umgebung, anstatt seine eigene zu verwalten, nachdem eine Warnung ausgegeben wurde.

Okay, an dieser Stelle sei angemerkt, dass #7002 zu diesem Zeitpunkt von 3 von 6 Pip-Betreuern genehmigt wurde.

Es schaltet pip standardmäßig von Nichtbenutzerinstallationen auf Benutzerinstallationen um, in den meisten Fällen, in denen wir sowieso Benutzerinstallationen durchführen sollten. Ich habe zwei größere Bedenken bei dieser Änderung, die wir klären sollten, bevor wir die Veröffentlichung vornehmen, die diese Verbesserung vornimmt.

  • Wollen wir einen Mechanismus, um Benutzerinstallationen explizit abzulehnen, sobald wir standardmäßig darauf umschalten? Wenn ja, wie würde es sich von --no-user unterscheiden? (Ich bin an Bord für die Umbenennung --no-user in --global als explizites Opt-out).
  • Was ist unsere "Übergangs"-Strategie?

    • Wie wollen wir diesen Wandel kommunizieren?

    • Sagen Sie den Benutzern, dass sie bei diesem Upgrade vorsichtig sein sollen?

    • Welche Arten von Problemen erwarten wir von Benutzern, wenn diese Änderung implementiert und veröffentlicht wird?

Ich würde sagen, --global ist falsch benannt, wenn Sie sich in einer Umgebung befinden. Für flit install ist das Gegenteil von --user --env , was ich ungefähr die "System-Python-Umgebung" einschließen wollte, aber ich denke, das ist auch nicht ganz klar. Vielleicht ist --no-user immer noch die beste Wahl - es ist eindeutig das Gegenteil von --user .

Ich denke, --no-user (oder die entsprechende Umgebungsvariable oder der entsprechende Konfigurationseintrag) sollte Ihnen das vorhandene Verhalten zurückgeben, da der Standardwert derzeit effektiv user = False ist.

Das einzige Szenario, das ich mir ausgedacht habe, wo die Änderung verwirrend wäre, ist, wenn Sie glauben, dass Sie die Berechtigung haben, in einer Umgebung zu installieren (mit aktivierter Benutzerseite, z. B. conda), wenn Sie dies tatsächlich nicht tun: Ein Fehler ist klarer als eine Benutzer installieren, auch wenn es eine Log-Meldung darüber gibt. Mir ist keine gute Möglichkeit eingefallen, das zu verbessern.

Es ist auch möglich, dass die Beschreibbarkeitserkennung schief geht. Ein falsch positives Ergebnis gibt Ihnen nur das vorhandene Verhalten (versuchen Sie, eine normale Installation durchzuführen, und scheitern Sie daran). Ein falsches Negativ würde eine Benutzerinstallation durchführen, wenn es eine normale hätte tun können.

Es schaltet Pip standardmäßig von Nicht-Benutzerinstallationen auf Benutzerinstallationen um.

Nicht (zum Beispiel) unter Windows, wo (standardmäßig) die Python-Installation eine Installation pro Benutzer ist und site-packages standardmäßig beschreibbar ist. Das ist etwas, was ich im Allgemeinen an #7002 bevorzuge, weil meine Erfahrung, seit diese Ausgabe (#1668) geöffnet wurde, ist, dass es viel zu einfach ist, mit "gemischten" Umgebungen in Konflikt zu geraten, in denen Pakete wie pip beide in Site-Paketen installiert sind und Benutzerseite. Daher bin ich jetzt dafür, Systeminstallationen durchzuführen, wenn dies überhaupt möglich ist, und Benutzerinstallationen nur in Fällen wie Linux-systemverwalteten Pythons durchzuführen, in denen Site-Pakete nicht geschrieben werden können.

Das gesagt:

  1. Es scheint keinen Sinn für eine --no-user -Option zu geben, da #7002 bedeutet, dass Sie nur dann eine Benutzerinstallation erhalten, wenn eine Systeminstallation ohnehin fehlschlagen würde.
  2. Das Wichtigste, was wir meiner Meinung nach in Bezug auf den Übergang kommunizieren müssen, ist, dass die Leute bei Mehrfachinstallationen sehr vorsichtig sein müssen, und das ist etwas, das nur durch das Verständnis und die Schulung der Benutzer bewältigt werden kann, nicht durch eine Problemumgehung in Pip. Es ist im Grunde ein zentrales Python-Problem. Wir könnten pip check erweitern, um zu melden, wenn es eine Site und einen Benutzer gibt, der ein Paket installiert und der Benutzer die Site beschattet, denke ich ...

Eine Option --no-user scheint keinen Sinn zu haben

Um es klar zu sagen, dies existiert bereits, obwohl es wahrscheinlich nicht oft nützlich ist. Wenn Sie user=true in einer Konfigurationsdatei haben, sollte --no-user das überschreiben.

Um es klar zu sagen, dies existiert bereits

Entschuldigung, ich hätte deutlicher sein sollen. Ich sehe keinen Sinn darin, "einen Mechanismus zum expliziten Ablehnen von Benutzerinstallationen zu haben, sobald wir standardmäßig darauf umschalten", zumindest in dem Sinne, wie ich annehme, dass @pradyunsg gemeint ist, bei dem es darum geht, das #7002-Verhalten abzulehnen ist nicht dasselbe wie "standardmäßig auf Benutzerinstallationen umzuschalten", wie ich sagte.

Eigentlich bin ich mir nicht sicher, ob das klarer ist ;-) Vielleicht möchte ich nur sagen: "Wir brauchen nicht mehr Optionen als die, die wir derzeit haben" ...

Hmm... @pfmoore Was ist nach #7002 erforderlich, um dieses Problem gelöst zu nennen?

PS: Ich hatte diesen früheren Kommentar in Eile geschrieben und er wurde versehentlich gepostet. Die Kugeln sind in Ordnung; Ich war noch dabei, den Absatz davor zu entwerfen, als er gepostet wurde. Bitte entschuldigen Sie die Verwirrung, die dadurch entstanden sein könnte.

@pradyunsg Angesichts der Tatsache, dass ich jetzt viel weniger der Meinung bin, dass --user als Standard eine gute Idee ist, es sei denn, es ist absolut notwendig (die Fälle Nr. 7002 Adressen), würde ich eher sagen, dass wir dieses Problem als aufgeben können keine gute Idee mehr, jetzt wo #7002 fertig ist.

Wenn wir Ihre 2 Aufzählungspunkte als Dinge betrachten, die wir möglicherweise benötigen, um # 7002 als vollständig zu zählen, decken meine obigen Kommentare dies ab.

Ich habe mich hier an die Release Notes gehalten.
https://pip.pypa.io/en/stable/news/#id3
"Standardmäßig wird eine Benutzerinstallation durchgeführt (als ob --user übergeben wurde), wenn das Hauptverzeichnis der Site-Pakete nicht beschreibbar ist und Benutzer-Site-Pakete aktiviert sind. (#1668)"

Meine Builds schlagen jetzt fehl

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

Dies scheint behoben zu sein, indem der --user aus meinen Pip-Befehlen entfernt wurde.

War das erwartetes Verhalten? Die Versionshinweise scheinen dies nicht widerzuspiegeln.

Link zum Skript, das jetzt auf pip 20.0.1 fehlschlägt (das Entfernen von --user behebt den harten Fehler)
https://github.com/lfit/releng-global-jjb/blob/master/shell/python-tools-install.sh

Wenn es richtig ist, dass Benutzer-Site-Pakete nicht aus dieser Umgebung importiert werden können, dann ist das das erwartete Verhalten, aber es ist orthogonal zu diesem PR. Diese Überprüfung wurde vor Jahren eingeführt (#567), aber es sieht so aus, als wäre sie bis vor kurzem mit venv unterbrochen worden (#7155). Dazu gibt es eine Release Note:

Korrekte Verarbeitung von System-Site-Paketen in virtuellen Umgebungen, die mit venv erstellt wurden (PEP 405).

Ah ja, danke für deine Kommentare. Ich habe das herausgefunden ...
Mein Skript füllte .local/bin/
als ich rannte

python3 -m venv ~/.local

und dann wird in einer Ubuntu-Anmeldeshell (#!/bin/bash -l) .local/bin zum Pfad hinzugefügt (der Aufruf von python3 ruft also jetzt die ausführbare .local/bin/python3-Datei auf), was wir nicht wollen.
Ich musste nie python3 -m venv ~/.local ausführen
oder rufen Sie meine Skripte von einer Login-Shell aus auf, und das Entfernen beider oder eines dieser Probleme behebt es.

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

Wenn wir also jemals die ausführbare Datei .local/bin/python ausführen, können wir die Pip-Installation nicht mit --user ausführen

Oh, ich hatte übersehen, dass du python3 -m venv ~/.local machst. Das kann Tools wie pip verwirren, da ~/.local das Präfix für --user -Installationen (unter Linux) ist. venvs und --user sind zwei _verschiedene_ Möglichkeiten, wie Sie Pakete installieren können, ohne systemweite Änderungen vorzunehmen: Sie sollten die eine oder andere verwenden. Das Erstellen eines Venv in ~/.local ergibt eine seltsame Mischung aus den beiden.

Das neue Verhalten ist vermutlich für viele bequem, aber 'Benutzer'-Installationen haben mir als Webentwickler etwas Kummer bereitet - ich muss oft virtuelle Umgebungen vorbereiten, die auf unseren Produktionsmaschinen bereitgestellt werden, und wenn irgendein Paket in meiner Benutzerbibliothek installiert ist, dann weigert sich pip standardmäßig, es in der virtuellen Umgebung zu installieren, die ich vorbereite, und wird trotzdem mit Erfolg beendet. Die Benachrichtigung, dass entschieden wurde, das Paket nicht zu installieren, ist in 30 oder 40 Seiten der Ausgabe des Skripts vergraben, das ich zum Vorbereiten der virtuellen Umgebung verwende. Der Endeffekt ist, dass nach der Bereitstellung von virtualenv die Pakete aus meinem Home-Verzeichnis nicht mehr verfügbar sind, sodass einige zufällige Pakete in meiner Produktions-Web-App fehlen und sie tot umfällt.

Ich gebe gerne zu, dass mein Anwendungsfall nicht der typische ist, also war dies vielleicht trotzdem eine gute Idee aus allgemeiner Usability-Sicht.

Für andere, die ähnliche Probleme hatten, gibt es einige Möglichkeiten, dies zu umgehen:

  • Fügen Sie --force-reinstall zu allen Ihren pip install Befehlszeilen in Skripten usw. hinzu
  • Löschen Sie ~/.local/lib/python* und bearbeiten Sie ~/.pip/pip.conf , um user = no im Abschnitt global hinzuzufügen:
[global]
user = no
  • Machen Sie etwas Drastischeres, ändern Sie zum Beispiel ~/.local/lib in eine Datei statt in ein Verzeichnis :smirk:

Wie immer, liebe Paketverwalter, vielen Dank für alles, was Sie tun – ich bin sicher, es ist praktisch unmöglich, etwas zu ändern, ohne das Zeug von jemandem zu beschädigen, und die Tatsache, dass Sie trotzdem weitermachen, ist eigentlich großartig, weil es uns Fortschritte machen lässt.

Ah, Benutzerinstallationen können auch große Probleme in Continuous-Integration-Umgebungen verursachen, in denen viele verschiedene Dinge unter demselben Benutzerkonto ausgeführt werden, aber die Leute immer noch erwarten, dass Builds voneinander isoliert sind. Wir haben dies gelöst, indem wir ~/.local schreibgeschützt gemacht haben, aber die oben genannten Lösungen würden wahrscheinlich auch funktionieren.

Wenn Sie eine virtuelle Umgebung mit den Standardoptionen erstellen, ist sie isoliert: Sie kann Ihre Benutzer- oder System-Site-Pakete nicht sehen, und folglich sollte pip nur mit Paketen funktionieren, die in der Umgebung installiert sind. Dies wurde vor vielen Jahren aufgrund genau der von Ihnen beschriebenen Probleme zur Standardeinstellung.

Wenn Sie virtualenvs mit der Option --system-site-packages erstellen (oder sehr alte Versionen von virtualenv, wo dies der Standard war), fungieren sie als Überlagerung der Pakete, die Sie sonst installiert hätten, sowohl systemweit als auch bei Ihnen zu Hause Verzeichnis. Wenn Sie Systempakete sichtbar haben möchten, aber keine Benutzerpakete, können Sie Python mit der Option -s oder der Umgebungsvariable PYTHONNOUSERSITE ausführen .

Oh! Es tut mir sehr leid, du hast vollkommen Recht. Die seltsame System-Site-Packages-Richtlinie meiner Organisation schlägt erneut zu. Danke für das Aufzeigen einiger Lösungen.

Kein Problem. System-Site-Pakete waren vor ein paar Jahren häufiger, als wir uns oft auf Systempaket-Manager für Dinge wie numpy verlassen haben, also lohnt es sich vielleicht, diese Richtlinie zu überdenken. Aber es mag auch heute noch sinnvolle Gründe geben, es einzusetzen.

Abschluss im Einklang mit https://github.com/pypa/pip/issues/1668#issuecomment -544569965.

Vielen Dank @takluyver! ^>^

@takluyver Vielen Dank für die Lösung des Problems, das mich schon lange beschäftigt
Aber ich habe festgestellt, dass bei der Installation von Paketen mit nicht privilegierten Benutzern Windows 10 Python 3.8.2 mit Pip 20.0.2 immer noch schwer fehlschlägt.

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'

Ich dachte, dies könnte daran liegen, dass $# errno von OSError errno.EACCES aber errno.EPERM ist.

@catPill bitte öffnen Sie ein neues Problem, damit es richtig nachverfolgt werden kann. Es ist durchaus plausibel, dass ich etwas unter Windows verpasst habe.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen