Pip: Erstellen Sie standardmäßig Installationsbefehle für Upgrade-Pakete

Erstellt am 8. Juni 2016  ·  99Kommentare  ·  Quelle: pypa/pip

  • Pip-Version: Zukünftige Versionen, hoffentlich 10.0
  • Python-Version: Alle unterstützt
  • Betriebssystem: Alle unterstützt

Basierend auf der Diskussion unter #59 besteht Interesse daran, den Installationsbefehl upgrade standardmäßig zu einem installierten Paket zu machen. Dieses Verhalten würde pip im Hinblick auf das Verhalten des Befehls install mit verschiedenen anderen Paketmanagern konsistent machen.

Dieses Thema soll der Ort für diese Diskussion sein, da es ein eigenes Thema verdient.

upgrade auto-locked

Hilfreichster Kommentar

Okay, ich ignoriere diese Diskussion für ein paar Tage, sie scheint sowohl auf der Sig als auch hier explodiert zu sein :)

Ich habe versucht, zu lesen, was in diesem Thread passiert ist, aber er ist lang und informationsdicht, sodass ich etwas übersehen könnte, aber Sie werden gleich eine Wand aus Wörtern bekommen.


Ich glaube nicht, dass es ganz fair ist zu sagen, dass das derzeitige Verhalten von pip install -U <foo> die Sicherheit der Menschen auf breiter Front erhöht. Ja, ich kann leicht auf einige Projekte wie PyCrypto oder Kryptographie hinweisen, bei denen Regressionen selten sind (insbesondere Sicherheitsregressionen) und neue Releases im Allgemeinen Verbesserungen der Sicherheit beinhalten. Ich denke, die Konzentration auf diese übersieht andere Fälle, beispielsweise den Fall, in dem eine neue Version von etwas auf PyPI einen Rückgang der Sicherheit verursacht hat. Ich denke, es gibt jedoch noch zwei andere Fälle, die beide darauf hinauslaufen können, dass ein Upgrade die Sicherheit überhaupt nicht beeinträchtigt oder nicht, sich jedoch darin unterscheidet, ob ein Upgrade für sie in Ordnung ist oder nicht.

Insgesamt denke ich nicht, dass rekursive Upgrades ein guter Sicherheitsmechanismus sind, und wenn eines unserer Ziele darin besteht, zu verhindern, dass Leute alte, unsichere Versionen von Software ausführen (und ich denke, es sollte ein Ziel sein), als ich denke, der Weg, um das zu erreichen Das heißt nicht, uns vom Verhalten von Upgrades abzuhängen (und nur zu beten und zu hoffen, dass sie zufällig in einiger Zeit ein Update ausführen), sondern stattdessen Zeit für eine dedizierte Lösung des Problems zu verwenden. Dies kann etwa pip list -o aber das explizit auf Sicherheitsprobleme prüft, kann den gesamten installierten Satz von Paketen gegen PyPI überprüfen, um zu sehen, ob irgendwelche Sicherheitsprobleme mit einem von ihnen bekannt sind, oder es kann dauern einige ganz andere Formate. Ich halte es jedoch für wichtig, dass dies nicht an eine halb verwandte Funktionalität gebunden ist und tatsächlich die gesamte Umgebung abdeckt und nicht nur das, was der Benutzer gerade verwendet. Wenn jemand einmal pip install requests[security] und dann von da an pip install -U requests – dann werden wir die Updates für pyopenssl und cryptogaphy komplett verpassen und so weiter wenn wir uns nur auf rekursive Upgrades verlassen.

Um die Sicherheitsbedenken für einen Moment beiseite zu schieben, müssen wir meiner Meinung nach einen Blick darauf werfen, welche Verhaltensweisen den Menschen am ehesten das geben, was sie wollen. Leider vermute ich, dass es bei einem so großen Ökosystem und mit so unterschiedlichen Anwendungsfällen wie Python keine einzige Antwort auf "was die Leute wollen" gibt. Hier werden einige miteinander verbundene Verhaltensweisen besprochen, also lassen Sie uns sie nacheinander angehen.

Für pip install --upgrade <foo> haben wir Beweise dafür, dass unser aktuelles Verhalten aktiv schädlich ist, so sehr, dass Projekte alles daran setzen, zu lügen, um zu verhindern, dass dieses Verhalten ausgelöst wird. Ich denke, wir sind uns alle einig, dass etwas, bei dem die Leute das Bedürfnis haben, aktiv zu untergraben (nicht nur in ihren eigenen Projekten, sondern auch für andere Projekte), wahrscheinlich einige Verfeinerungen der tatsächlichen Funktionsweise erfordert. In diesem Fall besteht die einzige wirkliche Lösung darin, ein Upgrade (oder Downgrade!) nach Möglichkeit zu vermeiden und die bereits installierte Version zu bevorzugen, _es sei denn_ der Benutzer hat ausdrücklich darum gebeten, _oder_ wir die Versionsbeschränkungen sonst nicht erfüllen können . Ich kann keine andere vernünftige Möglichkeit sehen, dies zu implementieren, die nicht versehentlich mehr als 30-minütige Builds auslöst, die möglicherweise zu einer Version führen, die für die vorliegende Aufgabe weniger geeignet ist (kein optimiertes BLAS oder so).

Sich dafür einzusetzen, dass das derzeitige Verhalten von pip install --upgrade so belassen wird, wie es ist, spricht sich im Wesentlichen gegen Projekte aus, die von numpy abhängen, weil sie ehrlich sind, ob sie von numpy abhängen oder nicht. Wenn jemand einen anderen Vorschlag hat, wie wir das numpy-Problem [1] lösen könnten, dann denke ich, dass er ihn ansprechen sollte.

Ich weiß, dass ein Vorschlag darin bestand, ein --non-recursive-upgrade Flag oder eine Art --upgrade-strategy Flag hinzuzufügen, aber ich denke, dass diese Ideen hauptsächlich nur dazu dienen, das mentale Modell zu komplizieren, das die Leute von Pip haben. Für die überwiegende Mehrheit der Pakete (insbesondere reine Python-Pakete, die keine sicherheitskritische Rolle spielen) spielt es keine große Rolle, ob wir sie aktualisieren oder nicht installierte Version (es sei denn, die Person findet einen Grund, eine Funktion oder einen Fehler, um _dieses_ Paket explizit zu aktualisieren). Wir leben hier jedoch in den Grenzfällen und ich sehe nur die beiden, die wirklich wichtig sind, schwer zu aktualisierende Pakete und sicherheitskritische Pakete, und wie ich oben erwähnt habe, denke ich, dass wir uns Sorgen machen werden, die Leute zu gewährleisten Sicherheits-Upgrades bekommen brauchen wir dafür einen echten Mechanismus, keine halbherzige Hoffnung, dass ein wichtiges Upgrade irgendwann in einem rekursiven Upgrade hängen geblieben ist. Angesichts der Tatsache, dass wir dedizierte Unterstützung für sicherheitsrelevante Themen benötigen, wird dies für die meisten Pakete keine Rolle spielen und für den schwer zu aktualisierenden Fall gibt es nur eine Antwort Begründung der laufenden Kosten für die Aufrechterhaltung einer ganzen Option dafür [2]. Ich denke auch, dass der konservativere Ansatz der offensichtlichste sein muss oder wir die Dinge nicht wirklich für die schwer zu aktualisierende Masse lösen. Wenn wir also eine neue Option hinzufügen würden, würden wir das Verhalten trotzdem ändern wollen von --upgrade standardmäßig und fügen Sie eine explizite Option hinzu, um den weniger konversativen/sicheren Ansatz für Upgrades zu erhalten.

Ich glaube nicht, dass wir einem Paket erlauben sollten, sich selbst für eifrige (oder nicht eifrige) Upgrades zu markieren. Ich denke, dies muss bei allen Paketen konsistent sein, damit Endbenutzer hoffen können, ein vernünftiges mentales Modell davon zu haben, was pip mit ihrem System anstellen wird, wenn sie einen Befehl ausführen. Abgesehen davon könnte ich sehen, dass wir die Möglichkeit hinzufügen, dass Leute Versionen auf PyPI als unsicher markieren und Leute warnen, wenn sie eine unsichere Version auf ihrem System installiert haben (oder zumindest, wenn sie eine installieren wollen).

Nun, da wir --upgrade , ist das andere zusammenhängende Thema hier, was wir mit pip install Vergleich zu pip install --upgrade tun sollen. Persönlich denke ich, dass wir beide dasselbe bedeuten sollten, _JEDOCH_ könnte es vernünftiger sein, die Diskussion zuerst nur auf das Verhalten von --upgrade und pip install vorerst in Ruhe zu lassen. Sobald wir die Lösung für das Upgrade gefunden haben, können wir angehen, was wir mit pip install selbst tun werden.

[1] Obwohl es ehrlich gesagt nicht eng mit Numpy zusammenhängt. Ich habe immer wieder Leute gesehen, die ihre Systeme oder ihre Installationen wegen einer unbeabsichtigten Ugprade kaputt gemacht haben. Es ist wahr, dass viele Projekte keine korrekten unteren Grenzen haben, aber ich glaube, es ist genauso wahr (oder mehr), dass sie auch keine korrekten oberen Grenzen haben. Eine besonders wichtige Sache ist, dass es möglich ist, die richtigen unteren Grenzen zum Zeitpunkt der Verpackung zu bestimmen, aber es ist unmöglich, die richtigen oberen Grenzen zu bestimmen.

[2] Optionen sind nicht kostenlos, sie verursachen Kosten und es ist wichtig zu versuchen, die Anzahl der Optionen so weit wie möglich zu reduzieren. Während man sie normalerweise nicht auf Null reduzieren kann, ist ein Muster, das ich bei OSS-Software viel zu oft sehe, der Wunsch, allen zu gefallen, indem immer mehr Optionen hinzugefügt werden, obwohl es in Wirklichkeit nur ein Mechanismus ist, um zu vermeiden, dass eine Entscheidung getroffen wird, die bei uns unpopulär sein könnte eine Gruppe von Menschen.

Alle 99 Kommentare

Okay, hier ist ein Vorschlag:

Endziel (wo wir enden wollen)

  • pip install foo : aktualisiert foo auf die neueste Version; führt auch die Mindestanzahl an Installationen/Upgrades durch, die erforderlich sind, um die Abhängigkeiten der neuen Version zu erfüllen
  • pip install -U foo / pip install --upgrade foo : identisch mit pip install foo (außer vielleicht sollten sie eventuell eine Warnung ausgeben?); zur Rückenkompatibilität aufbewahrt
  • pip require foo : wie das aktuelle pip install foo ; hat den gleichen Effekt wie die Installation eines Pakets mit Requires-Dist: foo . Dies ist eine seltsame Low-Level-Operation, die in den Dokumenten nicht hervorgehoben werden sollte, aber wir behalten sie vorerst bei, um einen weniger holprigen Übergang zu ermöglichen, und enthüllt eine sinnvolle Operation, die wir sowieso unterstützen müssen (die Requires-Dist Handhabung), daher ist es wahrscheinlich für einige Anwendungsfälle bei der Skripterstellung nützlich.
  • pip install --upgrade-recursive foo : wie das aktuelle pip install --upgrade foo -- stellt sicher, dass foo die neueste Version ist _und_ stellt sicher, dass alle transitiven Abhängigkeiten die neueste Version sind. Dies ist eine seltsame Randoption, die in den Dokumenten nicht hervorgehoben werden sollte, aber wir behalten sie vorerst bei, um einen weniger holprigen Übergang zu ermöglichen.
  • pip install --upgrade-non-recursive foo : wie das zukünftige pip install foo , aber explizit, um einen weniger holprigen Übergang zu ermöglichen.

Übergangsoption A

  • Phase 0: Was wir jetzt haben -- pip install foo führt kein Upgrade durch, pip install --upgrade foo führt ein rekursives Upgrade durch, pip require foo & pip install --upgrade-recursive foo sind Fehler
  • Phase 1:

    • wir fügen pip require foo , pip install --upgrade-recursive foo , pip install --upgrade-non-recursive foo .

    • pip install foo und pip install --upgrade foo verhalten sich weiterhin so, wie sie es jetzt tun, werden jedoch modifiziert, um zu überprüfen, was sie getan hätten, wenn --upgrade-non-recursive gesetzt worden wäre, und geben eine Veraltungswarnung aus, wann immer sie es tatsächlich tun tun, unterscheidet sich von dem, was sie in Zukunft tun werden.

    • Benutzer, die sich für das zukünftige Verhalten entscheiden (und die Warnungen stummschalten möchten), können die übliche Konfiguration verwenden, um --upgrade-non-recursive als Standard festzulegen (z. B. [install] upgrade-non-recursive = yes zu pip.conf hinzufügen).

  • Phase 2:

    • pip install foo und pip install --upgrade foo wechseln zum neuen Verhalten.

Übergangsoption B

KISS: Überspringe Phase 1 und gehe direkt von Phase 0 zu Phase 2. Begründung: Es ist nicht klar, ob dies tatsächlich etwas kaputt macht, die Leute werden in beiden Fällen etwas verwirrt und verärgert sein, es ist durchaus möglich, dass sie noch verwirrter sind und verärgert über den schrittweisen Übergang als über den tatsächlichen Wandel, haben wir begrenzte Ressourcen und sind begierig darauf, in die glänzende neue Zukunft zu gelangen.

In dieser Version können wir wahrscheinlich auch das Hinzufügen von --upgrade-non-recursive überspringen, da es sofort überflüssig ist, sobald es eingeführt wird.

Kommentar

Ich erwarte irgendwie, dass sich alle zurückdrängen und auf Übergangsoption A anstelle von Übergangsoption B bestehen. Aber eigentlich wäre ich mit beiden zufrieden, also lasse ich, anstatt präventiv Kompromisse einzugehen, es jemand anderem zu argumentieren (wenn sie wollen) :-).

Hmm, ich sehe den Mehrwert Ihres pip require ? Es sieht aus wie ein Duplikat von pip install ? Oder vielleicht ein pip install --no-upgrade ?

Ich bin mit Option B zufrieden.

Aber ich folge deiner Beschreibung nicht. Sie sagen pip require foo : dasselbe wie das aktuelle pip install foo . Es wird also ein Fehler auftreten, wenn foo installiert ist? Und pip install --upgrade-recursive foo : dasselbe wie das aktuelle pip install --upgrade foo . Ich dachte, es gäbe Probleme mit dem bestehenden install --upgrade Verhalten (außer dass es nicht die Standardeinstellung ist) - es gibt eine ganze Menge Diskussionen über die Notwendigkeit eines SAT-Solvers. Ist Ihr Vorschlag, dass wir nichts gegen diese Probleme unternehmen? Oder erinnere ich mich falsch und es gibt eigentlich kein Problem mit dem aktuellen --upgrade Verhalten?

Mit Variante B bin ich zufrieden.

Ich mag die Idee eines pip require Befehls aus den gleichen Gründen nicht, wie ich die geteilten pip install und pip upgrade Befehle nicht mochte. Zwei Befehle, die in etwa das Gleiche tun, aber die Leute nicht zwingen, eine Entscheidung darüber zu treffen, welchen sie im Voraus verwenden, im Gegensatz zu Flags. Ich denke auch, dass es für boolesche Flags (die etwas ein- und ausschalten) eine gute Praxis ist, überall dort, wo es Sinn macht, eine Umkehrung zu haben, damit die Leute Befehle besser komponieren können.

In Anbetracht dessen würde ich Folgendes tun:

  • pip install --upgrade ... jetzt standardmäßig ein "minimales" Upgrade durch und aktualisiert alles, was in der Befehlszeile/Anforderungsdatei genannt wird, auf die neueste Version, aktualisiert jedoch nur die Abhängigkeiten, wenn dies erforderlich ist.
  • pip install --no-upgrade ... verhält sich jetzt wie pip install , ähnlich wie Ihr pip require Befehl und stellt lediglich sicher, dass eine beliebige Version der Namensanforderungen installiert ist.
  • pip install ... hat seine Standardeinstellung von einem impliziten --no-upgrade auf ein implizites --upgrade umgestellt.

Sie werden vielleicht feststellen, dass es nichts wie das bisher aufgeführte aktuelle Verhalten gibt, eine Art Flag "alles im Abhängigkeitspfad auf die neueste Version aktualisieren". Ich bin unsicher, ob wir so etwas wirklich wollen (und wenn wir es wollen, wollen wir es für immer behalten oder wäre es nur eine vorübergehende Beilage, um den Übergang zu erleichtern). Eine andere Sache, die Sie bei dieser Entscheidung beachten sollten, ist, wie sich der theoretische pip upgrade Befehl auf diese Entscheidung auswirkt. Mit anderen Worten, wenn wir einen Befehl zum Aktualisieren aller installierten Elemente haben, können wir dann davon ausgehen, dass Leute jemals X und all seine Abhängigkeiten aktualisieren wollen?

Wenn wir so etwas wie das aktuelle Verhalten von --upgrade , dann sehe ich zwei Möglichkeiten:

  • --recursive / --no-recursive Um das alte oder das neue Verhalten zu aktivieren (aber was würden diese tun, wenn --no-upgrade ausgewählt wurde? Stille No-Op? Fehler?).
  • --upgrade-strategy=(minimal / recursive) , um zwischen zwei verschiedenen Strategien zu wechseln, etwas wortreicher als --[no-]recursive , macht es aber auch einfacher, zusätzliche Strategien hinzuzufügen, wenn wir jemals in der Not sind.

In Bezug auf den Dependency Resolver glaube ich nicht, dass diese beiden Probleme wirklich so sehr miteinander verflochten sind. Unsere Lösung ist derzeit sowohl im pip install als auch im pip install --upgrade Fall ein Problem, und ich glaube, dass dies auch weiterhin ein Problem mit den vorgeschlagenen Änderungen sein wird. Es ist etwas, das behoben werden muss, aber ich glaube nicht, dass es einen Einfluss auf das hat, was wir hier tun (obwohl es wahrscheinlich einen Einfluss auf den hypothetischen Befehl pip upgrade ).

Mir ist keine starke Anforderung für das aktuelle Verhalten bekannt (mit "stark" meine ich "alles andere als Abwärtskompatibilität"). Aber wenn die Leute es brauchten, können sie es bekommen, indem sie einfach alle Abhängigkeiten in der Befehlszeile auflisten.

Es ist ziemlich einfach, ein Skript zu schreiben, um alle (rekursiven) Abhängigkeiten eines Pakets anzuzeigen:

# reqs.py
import sys
from pkg_resources import get_distribution

def reqs(req):
    results = []
    queue = [get_distribution(req)]
    while queue:
        current = queue.pop()
        results.append(current)
        for r in current.requires():
            d = get_distribution(r)
            queue.append(d)
    return results

if __name__ == '__main__':
    print('\n'.join(sorted(set(d.project_name for d in reqs(sys.argv[1])))))

Dann machen Sie einfach pip install $(reqs.py foo) , um eine "eifrige Installation" von foo und seinen Abhängigkeiten zu erhalten. Ich bin mir sicher, dass dieser Ansatz Mängel aufweist, aber ist das Problem häufig genug, um eine komplexere Lösung zu rechtfertigen?

@pfmoore Nun, dieses Skript funktioniert nur, wenn sich zwischen den derzeit installierten Versionen und den zu aktualisierenden Versionen keine Abhängigkeiten geändert haben (und es wird natürlich davon

Davon abgesehen ist der einzige wirkliche Anwendungsfall, den ich mir vorstellen kann, die Installation eines Projekts in einer Umgebung, in der bereits Sachen installiert sind, aber die neueste Version der Abhängigkeiten haben möchte. IOW, ein Framework wie Pyramid könnte es vorziehen, dass neue Benutzer seine Abhängigkeiten mit dem rekursiven Upgrade installieren. ABER selbst in diesem Szenario (das das einzige ist, das ich mir vorstellen kann), wenn die Versionsspezifizierer der hypothetischen Pyramide alle korrekt sind, sollte der Endbenutzer erwarten, dass es unabhängig davon funktioniert (und es ähnelt dem, was die Leute bereits erhalten würden) im aktuellen pip install Verhalten mit etwas bereits installiertem).

Wenn jemand "Pyramide und alle ihre Abhängigkeiten auf dem neuesten Stand" haben möchte, ist dies etwas schöner als die vorgeschlagene Methode (die Kombination der beiden Vorschläge), die pip install Pyramid && pip upgrade (was nicht genau die ist) das gleiche, da pip upgrade mehr tun würde als nur Pyramide).

Das ist mein Zögern, ist, dass ich Schwierigkeiten habe, ein Szenario zu entwickeln, in dem es das Richtige ist, aber es könnte einige Randfälle mäßig schöner machen. Wir könnten es immer weglassen, und wenn wir auf Leute treffen, die danach fragen, fügen Sie es zu diesem Zeitpunkt wieder hinzu.

Ich mag sowohl A als auch B nicht. Ich mag weder die Idee, einen neuen Befehl einzuführen, noch möchte ich zu dem neuen Verhalten wechseln, ohne für das aktuelle Verhalten eine gewisse "Veraltungs"-Stilperiode zu haben. Daher habe ich unten meinen eigenen Vorschlag unterbreitet.

Mir ist keine starke Voraussetzung für das aktuelle Verhalten bekannt

Ich auch nicht. Ich möchte jedoch nicht den Arbeitscode von jemandem knacken, ohne es ihm zu sagen. Ich würde es unhöflich finden. 'Tue anderen nicht an, was du nicht willst, dass andere dir antun.' Aus diesem Grund möchte ich auch nicht ohne Warnung wie in der Option B von @njsmith wechseln.

Wenn jemand "Pyramide und alle ihre Abhängigkeiten auf dem neuesten Stand" haben möchte, ist dies etwas schöner als die vorgeschlagene Methode (die Kombination der beiden Vorschläge), die pip install Pyramid && pip upgrade (was nicht genau das ist) das gleiche, da ein Pip-Upgrade mehr tun würde als nur Pyramid).

So wie ich es verstehe, wenn jemand "Pyramide und alle seine Abhängigkeiten auf dem neuesten Stand" haben möchte, ist es nach der Umstellung auf das neue Verhalten pip install --upgrade-strategy=eager Pyramid . Das würde Pyramid und seine Abhängigkeiten eifrig auf die neueste Version aktualisieren, unabhängig davon, ob ein Upgrade unnötig ist.

Ich dachte, es wäre klar, dass wir sowohl die aktuellen "rekursiv-neuesten" als auch die neuen Standard-Upgrades "nur bei Bedarf" bereitstellen wollten. Betont nur, dass ich die allgemein akzeptierten Ideen posten muss.


Vorschlag

  1. Erstellen Sie eine Hauptversion, die das aktuelle Verhalten veraltet und eine Warnung bei der Verwendung dieser Befehle mit Opt-in-Flags und Konfiguration für das neue Verhalten ausgibt.

    • Flag(s) sollten bereitgestellt werden, damit der Benutzer das neue einzuführende Verhalten überprüfen kann. Die Verwendung der Flag(s) in dieser Version würde --upgrade implizieren.
    • _vielleicht_, pip install --upgrade warnt, dass dieses Flag in der nächsten Version nicht mehr verfügbar sein wird.
    • pip install warnt, dass sich das Verhalten in der nächsten Version ändert und das aktuelle Verhalten in der nächsten Version nicht verfügbar sein wird.

    Möglicherweise bieten beide Warnungen einen Link zu einer Dokumentation, die dem Benutzer vorschlägt, was er tun sollte.

  2. Wechseln Sie zu einem neuen Verhalten in der nächsten Hauptversion.

    • Wenn jemand das aktuelle Verhalten wirklich braucht, kann ein --no-upgrade Flag hinzugefügt werden. Aber ich will das nicht sehen, es sei denn, jemand braucht es wirklich.

Bikeshed : Optionen und Flags in 1. Ich bevorzuge es, --upgrade-strategy=(eager / non-eager / default) als Flag in 1 hinzuzufügen und die Standardstrategie in der 2. auf eager umzustellen.

Es lohnt sich auch ausdrücklich darauf hinzuweisen, dass dafür kein Dependency Resolver in pip erforderlich ist. Auch wenn es mit dem neuen Verhalten immer noch möglich ist, im gesamten Abhängigkeitsdiagramm eine gewisse Linienkante zu unterbrechen, wird dies weniger wahrscheinlich, wenn Sie seltener aktualisieren.

wie mit Abhängigkeiten umgegangen wird

Gleichmäßig unabhängig von der Tiefe. Der Benutzer kann zwischen eifrigen und nicht eifrigen Upgrades wählen. Sie sind so, wie ich sie in meiner früheren Beschreibung definiert hatte.

Was passiert mit Einschränkungen (und wenn sie kollidieren)

Ich würde sagen, was auch immer heute passiert.

Binär vs Quelle

Wird in #3785 behandelt. Bis dahin bleib so wie es ist.

Ich denke, es war klar, dass wir sowohl die aktuellen "rekursiv-neuesten" als auch die neuen Standard-Upgrades "nur bei Bedarf" bereitstellen wollten.

Nein, ich glaube nicht. Das Verhalten "nur bei Bedarf" wird meines Wissens von allen so vereinbart, wie wir es gerne zur Verfügung haben möchten. Aber ich habe verstanden, dass das derzeitige Verhalten allgemein als problematisch angesehen wird. Ob sich diese Probleme alle um das Problem "Pip braucht einen richtigen Abhängigkeitsauflöser" drehen, und wir sind damit einverstanden, das aktuelle Verhalten beizubehalten, bis das behoben ist, ich weiß es nicht wirklich.

Das Hauptproblem mit dem aktuellen Verhalten (das nicht wirklich auf das Fehlen eines echten Resolvers zurückzuführen ist) besteht darin, dass die "Gierigkeit" dazu führt, dass Dinge aktualisiert werden, die sonst möglicherweise nicht aktualisiert werden. Auf der Dose scheint das kein großes Problem zu sein, hat jedoch einige subtile (und einige nicht so subtile) Wechselwirkungen:

  • Es macht es wahrscheinlicher, dass etwas wie sudo pip versehentlich das Betriebssystem von jemandem zerstört, weil es wahrscheinlicher ist, dass wir in eine vom Betriebssystem bereitgestellte Abhängigkeit zurückkehren (selbst wenn der Benutzer, der pip aufruft, keine Ahnung hatte, dass dies betroffen wäre ).
  • Einige Bibliotheken sind sehr teuer zu installieren , insbesondere solche wie Numpy, bei denen das Kompilieren 30+ Minuten dauern kann.
  • Das rekursive Upgrade führt zu einer stärkeren Abwanderung des installierten Paketsatzes, was die Wahrscheinlichkeit erhöht, dass etwas, das bereits funktioniert hat, aufgrund eines Upgrades auf eine gemeinsame Abhängigkeit kaputt geht.

Die ersten beiden davon sind Dinge, die zumindest teilweise durch andere Lösungen behoben werden könnten (und für die diese Lösung auch keine vollständige Lösung ist). Sie könnten das Brechen des Betriebssystems beheben, indem Sie pip intelligenter machen, um nicht standardmäßig mit den Betriebssystemdateien herumzuspielen. Wheels machen es einfacher, selbst schwer zu bauende Bibliotheken wie Numpy zu installieren, aber nicht alles hat ein Wheel.

Die Abwanderung der installierten Komponenten wird nur durch diesen Patch behoben und das Auftreten der ersten beiden Probleme verringert (indem wir konservativer sind, wenn wir tatsächlich versuchen, etwas zu tun).

Natürlich ist dies ein sehr subtiler Unterschied und es ist schwer, alle genauen Vorteile zu benennen (sie würden genauer als Kompromisse und nicht als eine Reihe von Vorteilen beschrieben). Ich weiß nicht, ob das alte Verhalten etwas ist, das in den Fällen, in denen es nützlich ist, so nützlich ist, dass die Leute sich die Mühe machen, ein Flag dafür zu verwenden oder nicht. Wenn wir die Flagge hinzufügen, wird es schwierig, sie jemals zu entfernen, wenn wir sie jetzt nicht hinzufügen, könnten wir sie in Zukunft immer wieder hinzufügen, daher tendiere ich dazu, sie wegzulassen und abzuwarten, ob wir Bringen Sie die Leute dazu, nach einem Weg zu fragen, das alte Verhalten zurückzubringen.

Ich denke, es war klar, dass wir sowohl die aktuellen "rekursiv-neuesten" als auch die neuen Standard-Upgrades "nur bei Bedarf" bereitstellen wollten.

Nein, ich glaube nicht

Hmm... Ich dachte, dass beide Verhaltensweisen als nützlich angesehen wurden. Das hat mich das Pyramiden-Beispiel zum Nachdenken gebracht. Es verwendet das aktuelle Verhalten und macht genau das, was gewünscht wird.

Es scheint wünschenswert zu sein, sagen zu können "Upgrade pkg und all seine (Unter-)Abhängigkeiten auf die neueste Version". Ich möchte nicht _alles_ in meinem Ökosystem aktualisieren, ich möchte nur die neuesten Fehlerbehebungen für pkg und Abhängigkeiten erhalten.

  • Einige Bibliotheken sind sehr teuer zu installieren, insbesondere solche wie Numpy, bei denen das Kompilieren 30+ Minuten dauern kann.

Durch konservatives Aktualisieren von Paketen wird dies seltener der Fall.

Edit: Das hast du erwähnt.

  • Das rekursive Upgrade führt zu einer stärkeren Abwanderung des installierten Paketsatzes, was die Wahrscheinlichkeit erhöht, dass etwas, das bereits funktioniert hat, aufgrund eines Upgrades auf eine gemeinsame Abhängigkeit kaputt geht.

Dies _braucht_ einen zu behebenden Abhängigkeitsauflöser. Das halte ich für nicht in diesem Bereich.

Wenn wir die Flagge hinzufügen, wird es schwierig, sie jemals zu entfernen, wenn wir sie jetzt nicht hinzufügen, könnten wir sie in Zukunft immer wieder hinzufügen, daher tendiere ich dazu, sie wegzulassen und abzuwarten, ob wir Bringen Sie die Leute dazu, nach einem Weg zu fragen, das alte Verhalten zurückzubringen.

Das funktioniert bei mir ganz gut. Fügt hinzu, warum ich eine "veraltete" Version für das aktuelle Verhalten möchte, damit die Leute darum bitten, dass es beibehalten wird, anstatt es erneut hinzuzufügen.

Bearbeiten: s/version/verhalten/


:confused: Irgendwelche Kommentare zu meinem obigen Vorschlag?

  • Das rekursive Upgrade führt zu einer stärkeren Abwanderung des installierten Paketsatzes, was die Wahrscheinlichkeit erhöht, dass etwas, das bereits funktioniert hat, aufgrund eines Upgrades auf eine gemeinsame Abhängigkeit kaputt geht.
    Dies erfordert, dass ein Abhängigkeitsauflöser behoben wird. Das halte ich für nicht in diesem Bereich.

Nein, das hat nichts mit der Sache mit dem Abhängigkeitslöser zu tun. Dies ist nur "Software ist hart, und neue Versionen fügen manchmal neue Fehler hinzu, daher ist es umso wahrscheinlicher, dass Sie von neuen Fehlern gebissen werden, je mehr Abwanderung Sie haben".

Die stabilste (in Bezug auf neue, noch nicht aufgetretene Fehler) Software ist Software, die sich nie ändert.

Irgendwelche Anmerkungen zu meinem obigen Vorschlag?

Ich bin ein wenig besorgt darüber, für jeden Aufruf von pip install eine Warnung hinzuzufügen, aber ich bin nicht dagegen - es ist jedoch sicherlich der sicherere Weg und entspricht eher unserem typischen Einstellungsprozess und es gibt den Leuten die Möglichkeit, nach einer Option zu schreien, das alte Verhalten zu verwenden.

Ich denke, dass wir entweder das --upgrade Flag als Teil davon komplett ablehnen müssen (wahrscheinlich keine Operation machen und es für eine lange Zeit ausblenden), oder wir müssen --no-upgrade hinzufügen, um zu erhalten zurück zum alten Verhalten von pip install ... . Ich möchte nicht, dass eine ziemlich nutzlose --upgrade Flagge in unserer Hilfe herumliegt. Dann stellt sich die Frage für ein --[no-]upgrade Flag, ob wir das aktuelle Verhalten von pip install sinnvoll finden. Auch hier habe ich keine eindeutige Meinung-- Wir könnten die Einstellungsfrist noch einmal als Chance nutzen, um etwas zu sehen.

Irgendwelche Anmerkungen zu meinem obigen Vorschlag?

Ehrlich gesagt gefällt mir die Idee nicht, dass im Wesentlichen jeder Aufruf von pip install eine Warnung für einen vollständigen Hauptversionszyklus ausgibt. Das scheint garantiert nur die Benutzer zu ärgern, und als Ergebnis werden wir wahrscheinlich kein nützliches Feedback bekommen, nur viele Beschwerden über den Prozess.

Meine Präferenzen bleiben beim Ansatz von @njsmith - wahrscheinlich der Ansatz "einfach

Ich muss zugeben, dass es mir sehr schwer fällt, die Auswirkungen dieser verschiedenen Vorschläge auf meine tägliche Nutzung zu verstehen. Es werden viele Theorien und Randfälle diskutiert, wodurch die wichtigsten Punkte verschleiert werden. Ich denke, dass unabhängig vom Übergangsprozess, den wir anwenden, jemand an einer klaren Beschreibung der vorgeschlagenen Änderungen und ihrer Auswirkungen im Stil einer "Pressemitteilung" arbeiten sollte, die wir auf distutils-sig veröffentlichen können, bevor die Änderungen vorgenommen werden. Das sollte es uns ermöglichen, die Reaktionen der breiteren Community abzuschätzen. (Ich glaube nicht, dass dies eine PEP braucht, aber ich denke, es muss veröffentlicht werden).

Mein instinktives Gefühl ist, dass ich (leicht) glücklich sein werde über das neue "So wenig wie möglich"-Upgrade-Verhalten, leicht irritiert darüber, dass "install" jetzt ohne explizites Flag aktualisiert (aber ich werde mich hoffentlich daran gewöhnen .) einigermaßen schnell) und ansonsten meist gleichgültig. Meine Hauptverwendung wird wahrscheinlich pip install new_thing bleiben, um ein neues Paket zu installieren und ein manuelles "alle Paketnamen zu erhalten, und pip install <all of them at once> zu tun, um manuell "alle aktualisieren" zu simulieren". einen der Vorschläge (außer dass die neue "So wenig wie möglich"-Upgrade-Strategie den ungewollten, umständlichen Upgrade-Versuch vermeidet, den das aktuelle Verhalten mir zufügt).

Für mich kommt der Wendepunkt, wenn --prefer-binary und "Upgrade all" verfügbar werden. Diese werden sich auf meine Nutzung auswirken, und bis dahin werde ich keine Vorteile (oder Probleme) mit der Änderung der Upgrade-Strategie sehen.

Ehrlich gesagt gefällt mir die Idee nicht, dass im Wesentlichen jeder Aufruf von pip install eine Warnung für einen vollständigen Hauptversionszyklus ausgibt. Das scheint garantiert nur die Benutzer zu ärgern, und als Ergebnis werden wir wahrscheinlich kein nützliches Feedback bekommen, nur viele Beschwerden über den Prozess.

In der Tat. Ich dachte nicht daran, so eilig zu gehen. Hoppla!

Mein Punkt ist, dass ich wirklich möchte, dass pip selbst eine veraltete Hauptversion mit einer so großen Änderung des Hauptbefehls davon hat. Jede Form, die es annimmt, ich bin Spiel.

Ich denke, es ist der richtige Weg, selektiv zu sein, wann wir die Warnmeldung anzeigen.

Wie wählen Sie? @njsmith hat nur vorgeschlagen, wenn sich das Verhalten unterscheidet. Abgesehen von der Tatsache, dass die Arbeit, die bei jeder Installationsausführung geleistet wird, im Wesentlichen verdoppelt wird, halte ich es für eine gute Idee, solange wir dies gut veröffentlichen (im Voraus und im Detail).


bearbeiten

Oder vielleicht nicht beim zweiten Nachdenken. Es wird die Nachricht nicht allen zeigen, wie wir es gerne hätten. Ich würde es jedem mindestens einmal zeigen wollen.

Wie wäre es mit etwas Konfigurationsdatei-Magie, bei der der Benutzer aufgefordert wird, ein Flag in der Konfigurationsdatei zu setzen? Hier wäre ein --upgrade-strategy=default oder ein ähnliches Flag praktisch.

Irgendwelche alternativen Ideen dafür?


der Wendepunkt kommt, wenn --prefer-binary und "upgrade all" verfügbar werden. Diese werden sich auf meine Nutzung auswirken, und bis dahin werde ich keine Vorteile (oder Probleme) mit der Änderung der Upgrade-Strategie sehen.

Wahr. Während diese Änderung einige Probleme (unnötige Re-Installationen) direkt beheben wird, denke ich , wird es vielleicht indirekt andere Probleme zu beheben als auch.

Ähnlich wie bei der letzten Idee von @pradyunsg zeigt iirc git (irgendwie lange) Nachrichten an, wenn es eingeführt wurde oder eine große Änderung einführen wird, die Sie deaktivieren können, indem Sie eine Konfiguration über die Befehlszeile festlegen, die in der Nachricht erwähnt wird. Das hat mir bisher gut gefallen.

Eine vorübergehende Option zum Deaktivieren der Nachricht wäre nicht das schlechteste Verhalten.

@pradyunsg : Bevor wir uns mit den @dstufft und @pfmoore damit einverstanden sind, werde ich es wohl versuchen :-).) es ist ein komplexer Kompromiss – nicht zu wechseln ist auch auf verschiedene Weise unhöflich für verschiedene Leute. Zum Beispiel:

  • Je länger wir den Wechsel hinauszögern, desto länger fügen wir unseren Benutzern weiterhin das lästige aktuelle Verhalten zu. Beachten Sie, dass #59 199 Kommentare von 56 Teilnehmern enthält, von denen viele nur +1 sind. Sie noch ein Jahr warten zu lassen, ist auch ziemlich unhöflich.
  • Abschreibungsfristen sind kompliziert und schwierig – sie verursachen den Benutzern von Natur aus zusätzliche Kosten. Pip bekommt 10 Millionen Downloads/Monat allein von PyPI, so dass zB Ihre vorgeschlagene Nachricht mindestens 10 Millionen Mal angezeigt wird. Multiplizieren Sie damit, wie lange es dauert, so etwas zu lesen, eine Entscheidung zu treffen, eine Konfigurationsdatei zu aktualisieren usw.
  • Wenn dieser Sumpf jemals trockengelegt wird, müssen wir uns irgendwann bewegen. Es ist wirklich schmerzhaft, zwischen jeder Verbesserung ein Jahr zu warten.
  • Und Abschaffungszyklen sind für Entwickler kostspielig – wir haben bereits extrem, extrem knappe Entwickler-Ressourcen, daher ist es sehr teuer, Zeit damit zu verbringen, komplexe Abschreibungslogik zu implementieren, den Zeitplan zu verfolgen, ein Jahr später zurückzukommen und uns daran zu erinnern, was wir haben uns entschieden, etc. Das ist Zeit, die man damit verbringen könnte, das Warehouse zu verbessern, einen richtigen Resolver zu implementieren, --prefer-binary voranzutreiben, etc. etc. Es reicht nicht aus zu sagen "eine Veraltung ist wichtig", man muss argumentieren, dass es ist _mehr_ wichtiger als andere Dinge, die man mit dieser Zeit machen könnte.

8.1.2 hat die Deployments einer Reihe von Leuten aufgrund eines komplizierten Fehlers, der die Interaktion zwischen pip, pkg_resources und devpi beinhaltet, auf Hochtouren gebracht. Es war scheiße, aber die Leute haben sich damit befasst. Angesichts unserer begrenzten Ressourcen ist es eine Tatsache, dass wir manchmal Dinge kaputt machen und manchmal kaputte Dinge jahrelang ohne Fortschritt liegen lassen und den Benutzern im Allgemeinen Schmerzen bereiten. Wir können das nicht ändern, aber wir können zumindest klüger darüber sein, welche _Arten_ wir den Benutzern zufügen, und "Installation beginnt so zu funktionieren, wie viele Benutzer es bereits erwarten" ist ein viel produktiveres Ergebnis als die meisten :-).


@pfmoore :

Sie sagen pip require foo : dasselbe wie das aktuelle pip install foo . Es wird also ein Fehler auftreten, wenn foo installiert ist?
Nein, wenn foo bereits installiert ist, tut pip install foo nichts und wird erfolgreich beendet. Ich stellte mir vor, dass pip require eine Möglichkeit wäre, direkt mit dem Constraint-Resolver zu sprechen: "Hier ist ein neuer Constraint, bitte stellen Sie sicher, dass er erfüllt ist". Semantisch sinnvoll und gut definiert, aber eine ziemlich niedrige Benutzeroberfläche für Experten.

@dstufft : Ich finde pip install --no-upgrade foo ziemlich verwirrend - vom Namen her würde ich erwarten, dass es so etwas tun würde wie ... versuchen, foo zu installieren, aber Fehler ausgeben, wenn foo eine Abhängigkeit hatte, die das Upgrade von etwas erzwingen würde, das ich bereits installiert hatte? Was das Gegenteil von dem ist, was es tatsächlich tun würde. Für mich sind die Operation require und die Operation install konzeptionell sehr unterschiedlich -- siehe auch Guidos Kommentare dazu, wie Sie, wenn Sie jemals eine Funktion schreiben, die ein boolesches Argument benötigt, und wissen, dass Ihre Anrufer übergeben eine Konstante anstelle einer Variablen für dieses Argument, dann sollten Sie zwei Funktionen haben. Als ich es in einen neuen Befehl aufteilte, versuchte ich mir vorzustellen, wie es in einer Welt aussehen könnte, in der wir es um seiner selbst willen hinzugefügt haben, anstatt nur unserer Verpflichtung nachzukommen, eine --no Form von --upgrade oder was auch immer. Aber genauso gerne lasse ich es vorerst ganz fallen...


Okay, wie wäre es mit dieser Strategie:

  • 9.0 macht pip install foo = pip install --upgrade foo = nicht-rekursives Upgrade
  • Wir machen einen netten kleinen Bericht, der den tatsächlichen Effekt erklärt, den dies hat ( pip install foo jetzt aktualisiert, wenn foo installiert ist; pip install --upgrade foo aktualisiert nicht mehr alle Abhängigkeiten rekursiv)
  • Wir stellen ein Skript wie das von @pfmoore oben Versionshinweisen "Wenn Sie wirklich ein rekursives Upgrade wünschen, versuchen Sie dies ..."
  • Wir nehmen uns vor, in Zukunft einen pip require foo Befehl hinzuzufügen, wenn er sich als nützlich herausstellt, aber verschieben Sie das vorerst, weil es nicht wirklich eine Priorität hat und es einfacher ist, Dinge hinzuzufügen, als sie wegzunehmen
  • Wir behalten --upgrade auf unbestimmte Zeit als No-Op, aber nehmen es aus --help , und das Referenzhandbuch sagt nur "no-op; wegen Abwärtskompatibilität aufbewahrt". (Vielleicht reißen wir es in ein paar Jahren ganz heraus, vielleicht auch nicht – es ist mir egal und ich freue mich, diese Diskussion einfach zu verschieben, bis ein paar Jahre vergangen sind.)

Das vermeidet den schlimmsten grundlosen Bruch (es gibt keinen Grund für pip install -U foo , ein schwerer Fehler zu werden und Tonnen von bestehenden Tutorials ungültig zu machen), aber ansonsten bleiben die Dinge radikal einfach, sodass wir über Dinge wie --no-upgrade nachdenken können

Es scheint wünschenswert zu sein, sagen zu können "Upgrade pkg und all seine (Unter-)Abhängigkeiten auf die neueste Version". Ich möchte nicht alles in meinem Ökosystem aktualisieren, ich möchte nur die neuesten Fehlerbehebungen für pkg und Abhängigkeiten erhalten.

Das Problem dabei ist, dass es in vielen Fällen nicht wirklich sinnvoll ist, einer bestimmten Abhängigkeit eine Abhängigkeit zuzuweisen. Viele Leute haben Umgebungen mit ~30 verschiedenen installierten Paketen, von denen 1 numpy ist und 29 Pakete sind, die von numpy abhängen. Wenn ich also die neuen Bugfixes für Astropie möchte, sollte das mein Numpy aktualisieren? Das könnte einige Probleme mit Astropie beheben, aber es könnte auch die anderen 28 Pakete zerstören, wer weiß. Die Abhängigkeitskette von Pyramid enthält eine Reihe weit verbreiteter Dienstprogrammbibliotheken wie zope.interface und repoze.lru und setuptools (warum? idk). Ein rekursives Upgrade von Pyramid könnte also Twisted zerstören (was von zope.interface und setuptools und sonst nichts abhängt). Es gibt keine Möglichkeit, dass "Ich möchte die neuesten Fehlerbehebungen für Pyramid" impliziert "Ich möchte die neuesten setuptools " in den Köpfen der meisten Benutzer - aber so interpretiert pip install -U derzeit.

Ähnlich wie bei der letzten Idee von @pradyunsg zeigt iirc git (irgendwie lange) Nachrichten an, wenn es eingeführt wurde oder eine große Änderung einführen wird, die Sie deaktivieren können, indem Sie eine Konfiguration über die Befehlszeile festlegen, die in der Nachricht erwähnt wird.

Genau da kam mir die Idee.

Das hat mir bisher gut gefallen.

Dito. Daher würde ich es gerne in pip sehen. Es ist ein praxiserprobter Prozess.

Ich stimme zu, dass jede Warnmeldung ein bisschen zu viel ist, aber es die ganze Zeit anzuzeigen, bis der Benutzer darauf reagiert, ist etwas, von dem ich weiß, dass es von git selbst bei größeren Änderungen wie dieser funktioniert.

Gibt es eine Chance, dass ich Sie davon überzeugen kann, dass der Ansatz "Option B" in Ordnung ist?

Vielleicht. Sie haben Recht, die Kompromisse sind kompliziert und ein Jahr warten zu müssen, bis der Wechsel erfolgt, ist auch nicht die bequemste Sache. Es ist in Ordnung, bestimmte Nischenfälle zu durchbrechen, die nicht _jeder_ betreffen. Das wird einfach passieren. Hier ändern wir den am häufigsten verwendeten Befehl von pip (in der Dokumentation von Paketen und anderen). Dies ohne eine angemessene Vorlaufzeit zu tun, ist möglicherweise nicht das Beste. Dies sollte auch nicht geschehen, ohne den Leuten etwas Zeit zu geben, ihre Tools/Workflows/usw. so zu reparieren, dass sie mit dem neuen Verhalten arbeiten.

Mit dem aktuellen Vorschlag von @njsmith erhalte ich immer noch keine angemessene Warnung oder gebe den Leuten eine Vorschau auf die bevorstehende (große) Änderung. Das ist alles, aber es reicht, dass mir der Vorschlag nicht gefällt. Wenn mich jemand davon überzeugen kann, dass es in Ordnung wäre, diese beiden Anforderungen fallen zu lassen, und es möglich ist, die Leute richtig zu informieren, dass diese große Veränderung auf andere Weise auf sie zukommt, bin ich damit einverstanden.

Wenn wir die Details zur Deprecation richtig machen, sollte es möglich sein, dies so zu implementieren, dass das Material, das nur auf Deprecation-Release beschränkt ist, in einem Modul (Modul wie im Englischen; einer Klasse, Funktion oder etwas anderem) und dem nächsten Major verbleibt release beendet einfach das Aufrufen dieses Moduls und entfernt es. Auf diese Weise wird zumindest der Nacharbeitsaufwand minimiert.

59 hat 199 Kommentare von 56 Teilnehmern, viele davon nur +1. Sie noch ein Jahr warten zu lassen, ist auch ziemlich unhöflich.

Sie _müssen_ nicht noch ein Jahr warten. Sie können sich einfach für das neue Verhalten anmelden. Wir geben nur den Leuten Zeit, deren Sachen aufgrund der Veränderung kaputt gegangen sind. Andere können sich einfach für das nettere Verhalten entscheiden.

Wir behalten --upgrade auf unbestimmte Zeit als No-Op bei, aber nehmen es aus --help heraus, und das Referenzhandbuch sagt nur "no-op; aus Gründen der Abwärtskompatibilität behalten". (Vielleicht reißen wir es in ein paar Jahren ganz heraus, vielleicht auch nicht – es ist mir egal und ich freue mich, diese Diskussion einfach zu verschieben, bis ein paar Jahre vergangen sind.)
[schnipsen?]
Das vermeidet den schlimmsten grundlosen Bruch (es gibt keinen Grund, dass pip install -U foo zu einem harten Fehler wird und Tonnen von bestehenden Tutorials ungültig macht)

Wenn es nicht offensichtlich wäre, würde dies in meinem Vorschlag 1 passieren. Niemand wird durch die Anwesenheit von -U Operation gestört. Seine Abwesenheit wird die Dokumentation vieler Pakete ungültig machen und Sachen kaputt machen. Wir bewahren es auf, bis es selten genug ist, um sicher entfernt zu werden. Diese Diskussion sollte einige Jahre später stattfinden. (lasst uns dafür den 16. September 2018 markieren, ohne jeglichen Grund)

Unabhängig davon, ob ich meine Position zum Vorschlag von @njsmith ändere , behalten wir nach der --upgrade .


Es gibt keine Möglichkeit, dass "Ich möchte die neuesten Bugfixes für Pyramid" in den Köpfen der meisten Benutzer impliziert "Ich möchte die neuesten Setuptools" - aber so interpretiert pip install -U es derzeit.

Wahr. Dies ist jedoch auf das Fehlen eines Dependency Resolvers zurückzuführen. Sobald es hinzugefügt wurde, macht es _genau_ das, was der Benutzer wollte. Bis dahin können wir nur noch so viel tun. Das Hinzufügen einer Warnung in der Dokumentation über die mögliche Unterbrechung der Abhängigkeiten ist für IMO vorerst ausreichend, da dieses Verhalten zu einem Opt-in werden soll. Und dies setzt voraus, dass die Pakete ihre Versprechen halten, die durch Versionsnummern gemacht wurden. Wenn sie kaputt gehen, kann pip wenig tun, bis Pakete ihre Versionsspezifizierer verfeinern.

Nebenbei denke ich, dass es eine Dokumentation geben sollte, in der erwähnt wird, dass pip Ihre Abhängigkeitsdiagramme unterbrechen kann.

Wenn ich also die neuen Bugfixes für Astropie möchte, sollte das mein Numpy aktualisieren?

Nicht, wenn es Ihr Abhängigkeitsdiagramm durchbricht. Auch nicht, wenn es Ihr gut konfiguriertes Numpy entfernt. Der erstere Fall benötigt einen Abhängigkeitsauflöser. Letzteres muss Upgrades "zurückhalten". Beides außerhalb des Rahmens dieser Diskussion.

Bis wir diese bekommen, können wir den Leuten höchstens sagen: "Pip macht nicht immer das Richtige und wir haben nicht die Ressourcen, um es zu beheben. Hilfe wäre dankbar."


Dies ist nur "Software ist hart, und neue Versionen fügen manchmal neue Fehler hinzu, daher ist es umso wahrscheinlicher, dass Sie von neuen Fehlern gebissen werden, je mehr Abwanderung Sie haben".

Ich kann nur sagen, traurig aber wahr.

Ich poste, was das mentale Bild des Verhaltens nach der Einstellung in meinem Kopf ist ... Nur um sicherzustellen, dass ich die Bedenken von niemandem übersehe.

  • pip install Upgrades ohne Eifer durch, Upgrades von Abhängigkeiten nur bei Bedarf.

    • TBD: Wenn Sie auch ein No-Op-Flag hinzufügen möchten, das vom Veraltungspfad abhängt

  • pip install --some-flag aktualisiert eifrig und aktualisiert Abhängigkeiten auf die neueste Version, die von Versionsspezifizierern erlaubt ist.

    • TBD: wenn gewünscht

  • --upgrade wird zu einem No-Op. Es wird in install --help , dokumentiert als "für Abwärtskompatibilität aufbewahrt".

    • TBD, wenn es aus der Hilfe entfernt wird, sage ich nein

  • pip require wird verschoben, bis jemand vorbeikommt und danach fragt. Wie unten angemerkt, kann dies nicht der Fall sein. (Edit: es stellte sich später heraus, dass ich falsch lag.. :| )

Nachdem wir uns für das erforderliche Verhalten entschieden haben, beginne ich mit der Umsetzung. (Ich mache mich gerade noch mit den Implementierungsdetails von pip install und #3194 vertraut.)

Lassen Sie uns das Verhalten und die Art und Weise, wie wir die Einstellung hier durchführen wollen, abschließen und wir werden die Optionsnamen in der PR, die ich schließlich mache, radeln.


pip install --target <dir> ist dokumentiert als "Standardmäßig werden vorhandene Dateien/Ordner in

."

Da install jetzt standardmäßig mit dem Upgrade (Ersetzen) beginnen soll, scheint es konsequenter zu sein, die vorhandenen Dateien und Ordner standardmäßig zu ersetzen und ein Flag bereitzustellen, wenn der Benutzer das ältere Verhalten des Nicht-Ersetzens wünscht. AFAIK, diese Flagge ist unentschlossen. pip require hat Ähnlichkeiten. Ich denke, wir können die Diskussion über pip require nicht verschieben und müssen es jetzt tun.

Die Überschneidung mit pip install und die Notwendigkeit, die von install --target lässt mich das require Verhalten hinter einem Flag in install .

@pradyunsg :

Hier ändern wir den am häufigsten verwendeten Befehl von pip (in der Dokumentation von Paketen und anderen). Dies ohne eine angemessene Vorlaufzeit zu tun, ist möglicherweise nicht das Beste. Dies sollte auch nicht geschehen, ohne den Leuten etwas Zeit zu geben, ihre Tools/Workflows/usw. so zu reparieren, dass sie mit dem neuen Verhalten arbeiten.

Es ist der am häufigsten verwendete Befehl von pip, aber wir berühren nur zwei seltsame Eckfälle: pip install foo wo foo bereits installiert ist und pip install -U foo wo foo eine rekursive Abhängigkeit hat, die veraltet ist. Obwohl ich mir sicher bin, dass es bei allen unseren Aktivitäten zu obskuren Fehlern kommen wird, fallen mir keine vernünftigen Tools oder Arbeitsabläufe ein, die dadurch kaputt gehen würden. Können Sie ein Beispiel dafür geben, woran Sie denken?

Wahr. Dies ist jedoch auf das Fehlen eines Dependency Resolvers zurückzuführen. Sobald es hinzugefügt wurde, macht es genau das, was der Benutzer wollte.

??? keine Ahnung, was Sie hier meinen -- Pyramid hängt rekursiv von setuptools ab, und mein Argument ist, dass dies zeigt, dass "Paket und seine rekursiven Abhängigkeiten" eigentlich keinem sinnvollen Konzept im mentalen Modell des Benutzers entsprechen. AFAICT dies ist völlig orthogonal zum Problem des Abhängigkeitsauflösers?

pip install --target <dir> ... Da die Installation nun standardmäßig mit dem Upgrade (Ersetzen) beginnen soll, scheint es konsequenter zu sein, die vorhandenen Dateien und Ordner standardmäßig zu ersetzen

Ich denke, das Problem mit pip install --target <dir> ist, dass es sich nicht wirklich in einer Umgebung installiert – es wird für Dinge wie Vendoring verwendet. Und ohne Umgebung macht die Unterscheidung zwischen Upgrade und Installation keinen Sinn. Meine Stimme ist, dass wir es in Ruhe lassen – das derzeitige Verhalten ist IMO in Ordnung.

pip require hat Ähnlichkeiten.

Es tut?

wir berühren nur zwei seltsame Eckfälle: pip install foo, wo foo bereits installiert ist, und pip install -U foo, wo foo eine rekursive Abhängigkeit hat, die veraltet ist.

Hm... In der Tat. Obwohl die Änderung groß ist, stimme ich zu, dass es nur seltsame Eckfälle sind, die wir durchbrechen. Aber ich möchte wirklich einige Benutzereingaben erhalten, bevor ich die Änderung vornehme ... Es fühlt sich nicht richtig an, eine solche Änderung ohne eine Einstellung vorzunehmen.

Wenn alle anderen hier (hauptsächlich @pfmoore und @dstufft) sagen, dass sie einen Wechsel ohne Veraltung einem veralteten Wechsel vorziehen, werde ich wohl damit einverstanden sein , den Vorschlag von

Wahr. Dies ist jedoch auf das Fehlen eines Dependency Resolvers zurückzuführen. Sobald es hinzugefügt wurde, macht es genau das, was der Benutzer wollte.

Pyramid hängt rekursiv von setuptools ab, und mein Argument ist, dass dies zeigt, dass "Paket und seine rekursiven Abhängigkeiten" eigentlich keinem sinnvollen Konzept im mentalen Modell des Benutzers entsprechen.

Ich bin nicht einverstanden. Es ist sinnvoll, die neueste mögliche Version eines Pakets und seiner Abhängigkeiten zu erhalten. Wenn ich beispielsweise festgestellt habe, dass in meiner aktuellen Umgebung ein Problem mit pkgA aufgetreten ist, möchte ich die neuesten Versionen davon und alle Abhängigkeiten überprüfen, um die Möglichkeit auszuschließen, dass dies ein Problem ist, das in einer neuen Version behoben wurde . Ich denke, es ist vernünftig zu erwarten, dass das möglich ist.

Um es klar zu sagen: Lassen Sie uns das alte Verhalten nicht aus dem einfachen Grund bereitstellen, weil es faulen Menschen eine Möglichkeit bietet, das vorhandene Verhalten beizubehalten, wenn es für sie funktioniert. Wir behalten es nur, wenn wir einen gültigen Anwendungsfall herausfinden. Wenn wir den veralteten Pfad durchlaufen, ist es veraltet, aber bis zum Ende der Einstellung verfügbar. Wenn jemand dieses Verhalten will, wird er sagen, dass er es tut, und wir werden es aus der Ablehnung herausziehen und es bleiben lassen.

AFAICT dies ist völlig orthogonal zum Problem des Abhängigkeitsauflösers?

Der Dependency Resolver kommt ins Spiel, wenn A und B beide von C abhängen, A rekursiv aktualisiert wird und C für B bricht B kümmert, wenn es A . Dies war das Beispiel, das Sie gegeben haben, wobei Pyramid, Twisted und zope.interface A, B bzw. C sind.

pip require hat Ähnlichkeiten.

Es tut?

Ja, da es sich auch nicht auf bereits installierte Pakete auswirkt. Aber wenn man dies überprüft, unterscheiden sie sich mehr als ähnlich. Diese Option ähnelt eher --avoid-installed . Ich weiß nicht, warum ich dachte, sie seien ähnlich genug, um zu verschmelzen...

@njsmith

Nein, wenn foo bereits installiert ist, tut pip install foo nichts und wird erfolgreich beendet

Was ich sehe ist

>pip install xlrd
Requirement already satisfied (use --upgrade to upgrade): xlrd in c:\users\uk03306\appdata\local\programs\python\python35\lib\site-packages

Ich bin mir beim Exit-Status nicht sicher, ich dachte an die Benutzererfahrung. Entschuldigung, ich war nachlässig in meiner Formulierung - ich meinte, dass ich "eine Fehlermeldung bekomme" (vielleicht ist es technisch eine Warnung), anstatt dass pip den Exit-Code auf Fehler setzt. Aber so oder so ist es ein kleiner Punkt.

Auf andere E-Mails antworten:

Ich stimme @njsmith zu, dass die @pradyunsg Wenn Sie immer noch der Meinung sind, dass wir Benutzer warnen sollten, dann posten Sie auf jeden Fall auf distutils-sig (und sogar auf Python-Liste, wenn Sie es für gerechtfertigt halten) und geben Sie den Plan dort bekannt. Es besteht die Gefahr, dass dies zu noch mehr Fahrradabwurf und Debatten führt, die produktiv sein können oder nicht, aber das liegt in der Natur von Verpackungsänderungen :-)

Ich bin auch der Meinung, dass ich "Pyramid und all seine Abhängigkeiten" nicht als besonders nützlich halte, um es aktualisieren zu wollen. Pyramide selbst, natürlich. Und wahrscheinlich Pyramiden- und _selected_-Abhängigkeiten. Und sicherlich "alles in dieser virtuellen Umgebung (die für meine Pyramid-Entwicklung eingerichtet wurde)".

Was führt zu dem Gedanken - wie oft würden Leute, die nach eifrigen Upgrades fragen, besser bedient werden, wenn sie virtualenvs und upgrade-all verwenden? Ich kann nicht für die Arbeitsabläufe anderer Leute sprechen, aber es ist sicherlich meine Art zu arbeiten. Und natürlich sind für viele Umgebungen pip freeze und genaue Versionsbeschränkungen die Norm, so dass eifrige Updates dort unangemessen wären.

Schließlich haben wir "Pip braucht einen Löser" von diesem Vorschlag entkoppelt - also zu argumentieren, dass Eifer nützlich ist, sobald wir einen Löser haben, ist im Moment nicht relevant. Aktuelles Eifer-Verhalten kann Abhängigkeiten aufheben – also sollten wir es entfernen und dann vielleicht wieder eine funktionierende Version einführen, sobald wir einen Solver haben und wir Feedback bekommen haben, dass (eine nicht kaputte Version davon) die Funktion für die Leute nützlich ist.

Wenn Sie immer noch der Meinung sind, dass wir Benutzer warnen sollten, dann posten Sie auf jeden Fall auf distutils-sig (und sogar auf python-list, wenn Sie es für gerechtfertigt halten) und geben Sie den Plan dort bekannt.

Ich denke, die Ankündigung auf distutils-sig klingt für mich gut. Python-Liste, ich werde darüber nachdenken.

Es besteht die Gefahr, dass dies zu noch mehr Fahrradabwurf und Debatten führt, die produktiv sein können oder nicht, aber das liegt in der Natur von Verpackungsänderungen :-)

Das ist ein Kompromiss. Ich schätze, ich werde sie an die PR für das Bikeshedding weiterleiten und andere Kommentare in die Mailingliste aufnehmen...

Kurze Korrektur: Ich hätte wirklich den gesamten Hilfetext von --target erwähnen sollen.

""" Pakete installieren in

. Standardmäßig werden vorhandene Dateien/Ordner in nicht ersetzt. Verwenden Sie --upgrade, um vorhandene Pakete in zu ersetzenmit neuen Versionen. """

Wenn wir --upgrade einem No-Op machen, sollte --target nicht davon abhängen. Wir müssen das herausfinden.

Schließlich haben wir "Pip braucht einen Löser" von diesem Vorschlag entkoppelt - also zu argumentieren, dass Eifer nützlich ist, sobald wir einen Löser haben, ist im Moment nicht relevant. Aktuelles Eifer-Verhalten kann Abhängigkeiten aufheben – also sollten wir es entfernen und dann vielleicht wieder eine funktionierende Version einführen, sobald wir einen Solver haben und wir Feedback bekommen haben, dass (eine nicht kaputte Version davon) die Funktion für die Leute nützlich ist.

Klingt gut für mich. Ich denke, wir können das eifrige Upgrade-Verhalten fallen lassen. Es ist einfach, es hinzuzufügen, wenn wir es brauchen. Entfernen (nach dem Schalter), nicht so sehr. Ich denke, es ist eine gute Idee, es nicht bereitzustellen und die Verwendung von virtualenv für den Job zu befürworten.

@pfmoore Ich Nichtabschreibung gehen möchten.

Ich bin auch der Meinung, dass ich "Pyramid und all seine Abhängigkeiten" nicht als besonders nützlich halte, um es aktualisieren zu wollen. Pyramide selbst, natürlich. Und wahrscheinlich Pyramid und ausgewählte Abhängigkeiten.

Wenn Sie es so ausdrücken, ist es verständlich, warum das, was ich gesagt habe, nicht ideal ist.

Aktuelles eifriges Verhalten kann Abhängigkeiten durchbrechen

Ich denke, jede Paketänderung hat das Potenzial dazu. Das nicht eifrige Verhalten reduziert nur die Anzahl der Änderungen und umgeht dieses Problem daher ziemlich gut genug, um Brüche erheblich zu reduzieren.

Wie auch immer, ich nehme an, dass beschlossen wurde, eifrige Upgrades fallen zu lassen.

Wir müssen das herausfinden.

Vielleicht --force-reinstall wiederverwenden? Ich weiß nicht genug über diese Optionen, um sicher zu sein ...


@dstufft Ich warte auf Ihre Meinung zu

So bleiben uns nur --upgrade und --target übrig. (und @dstuffts Stimme)

Ich bitte jeden, der Probleme/Anforderungen hat, die seiner Meinung nach nicht behandelt wurden, diese jetzt zur Sprache zu bringen. Nicht, dass es die letzte Chance wäre oder so, nur ein guter Zeitpunkt dafür.

Aktuelles eifriges Verhalten kann Abhängigkeiten durchbrechen
Ich denke, jede Paketänderung hat das Potenzial dazu.

Speziell aktuelles Eager-Verhalten kann das System in einen Zustand bringen, in dem deklarierte Abhängigkeitsanforderungen (die nicht inkonsistent oder anderweitig gebrochen sind) verletzt werden, wenn dies zuvor nicht der Fall war. Das ist nicht akzeptabel und sollte von einem "richtigen Löser" angegangen werden. Für die einfacheren Upgrades "nur nach Bedarf" ist mein Verständnis, dass das Risiko eines solchen Bruchs auch ohne Solver minimiert wird.

So bleiben uns nur --upgrade und --target übrig.

Abgesehen davon, dass der Hilfetext von --target , dass er sich nicht auf --upgrade bezieht, halte ich --target für nicht gültig. Der Hilfetext ist

Installieren Sie Pakete in <dir> . Standardmäßig werden vorhandene Dateien/Ordner in <dir> . Verwenden Sie --upgrade, um vorhandene Pakete in <dir> durch neue Versionen zu ersetzen.

Ich schlage vor, wir ersetzen es einfach durch

Installieren Sie Pakete in <dir> .

Vermutlich ändert sich die Standardeinstellung (wie bei der normalen "Installation") in standardmäßig überschreiben, und wenn Sie nicht überschreiben möchten, führen Sie einfach den Installationsbefehl nicht aus (genauso wie bei der Installation in Site-Paketen). . Wenn Benutzer etwas Komplexeres wünschen, können sie die entsprechenden Befehle ausarbeiten. Machen wir uns keine Sorgen um Vorschläge (die in der Praxis hilfreich sein können oder nicht).

Der Hilfetext ist

Pakete installieren in

. Standardmäßig werden vorhandene Dateien/Ordner in nicht ersetzt. Verwenden Sie --upgrade, um vorhandene Pakete in zu ersetzenmit neuen Versionen.

Ich schlage vor, wir ersetzen es einfach durch

Pakete installieren in

.

Hmm... Sind Sie sicher, dass Sie die Funktion entfernen möchten, vorhandene Dateien/Ordner nicht zu ersetzen?

Sind Sie sicher, dass Sie die Funktion entfernen möchten, vorhandene Dateien/Ordner nicht zu ersetzen?

Ich war es nicht, der das befürwortete - @dstufft und @njsmith argumentierten stark, dass "install" aktualisiert werden sollte, wenn ein bereits installiertes Paket bereitgestellt wird. Das einzige, was ich hinzufüge, ist, dass das Verhalten meiner Meinung nach nicht anders sein sollte, nur weil der Benutzer --target .

Vielleicht ist eine Option --no-replace erforderlich, aber wenn ja, sollte sie sowohl für --target als auch für Nicht- --target Installationen gelten.

Off Topic

Um den Preis wählerischer zu sein, ein winziger Abschlagsvorschlag/Anfrage/Tipp/{whatever_you_want_to_call_it} - Lassen Sie eine leere > Zeile im Block-Zitat, damit es sensibel wird ... Andernfalls geht es einfach in das übergeordnete Zitat über ...

> > > A
> >
> > B
> C
>
> D

EIN

B
C

D

Beachten Sie, wie B und C auf die gleiche Ebene des Zitierens gekommen sind, aber D tatsächlich den Zahn bekommen hat ...

Vielleicht ist eine Option --no-replace erforderlich, aber wenn ja, sollte sie sowohl für --target als auch für Nicht- --target Installationen gelten.

:+1:

Um den Preis, wählerisch zu sein, ein kleiner Abschlagsvorschlag/-antrag/-tipp

Vielen Dank. Ich versuche, "Vorschau" zu machen, aber das habe ich verpasst.

Ich beginne am Montag meine Implementierungsarbeiten off-Master. Wir sind fast über fast alles entschieden und selbst wenn @dstufft sagt, dass wir die

Folgendes werde ich mit der Implementierung beginnen:

  • --upgrade bleibt, wird aber ein No-Op. Sein Wert wird nirgendwo verwendet.

    • Ich behalte es in --help .

  • pip install führt Upgrades ohne Eifer durch und aktualisiert Abhängigkeiten nur bei Bedarf.
  • Keine eifrigen Upgrade-Optionen. Das aktuelle Verhalten wäre nicht verfügbar.
  • Wird --no-replace implementieren, das es nicht erlaubt, Pakete über andere Pakete zu installieren und ohne Fehler fortzufahren (wie das aktuelle pip install pkgA für pkgB macht, wenn pkgA nicht installiert ist, pkgB installiert ist und pkgA von pkgB abhängt) .

Ich denke, wir haben beschlossen, dass wir --upgrade vorerst beibehalten (aus Gründen der Abwärtskompatibilität), aber nicht wegen der Einstellung und _eventuellen_ Entfernung. Sollte es mit dem normalen veralteten Zyklus ab Version 9.0 entfernt werden (ich denke, es ist in Ordnung, wenn wir es in 10.0/11.0 entfernen ...)?


Nebenbei bemerkt, dachte ich, da diese Änderung die nächste Hauptversion zu einer absichtlich abwärts-inkompatiblen Version machen wird; Wäre es sinnvoll, darauf zu drängen, dass einige andere Probleme in derselben Version behoben werden? Wenn ja, gibt es solche Probleme?

Es würde helfen, den Nutzen unserer Entscheidung zu maximieren, die Abwärtskompatibilität zu brechen.

warte auf @dstuffts Kommentar

edit: "am Montag" hinzugefügt, Sachen verschoben.

Hallo.

Ich entschuldige mich schnell für die mangelnde Aktivität in der letzten Woche... Einige andere dringende Arbeiten kamen auf mich zu und nahmen einige meiner Zeit in Anspruch. Jedenfalls habe ich begonnen, an der Implementierung dieses Problems zu arbeiten.

@pradyunsg : Ich verstehe nicht, wofür --no-replace ist. --target ist ein Weirdo Option , dass fast veraltet wurde vor ein paar Monaten, und er kann auf lange Sicht nicht überleben, also wenn es für ist --target speziell dann ist es sehr niedrige Priorität und ich würde nicht‘ Mach dir vorerst keine Sorgen darüber.

Derzeit hat --target eine _Abhängigkeit_ von --upgrade . Das aktuelle (Standard-) Verhalten von --target besteht darin, Dateien und Ordner, die sich bereits im Zielverzeichnis befinden, nicht zu ersetzen. Die Übergabe von --upgrade ändert dies, um Dateien und Ordner zu ersetzen, die sich bereits im Zielverzeichnis befinden.

Da install nun standardmäßig Pakete ersetzt (Leseaktualisierungen) ist es sinnvoll, das Standardverhalten von install --target entsprechend zu ändern. Dies wäre --upgrade ein nutzloses Flag für --target , was wir wollen ( --upgrade ein No-Op werden, das schließlich entfernt werden würde). Dann müsste eine neue Option zum aktuellen Verhalten von --target . Dies ist das --no-replace .

Wenn --no-replace dann aus Konsistenzgründen mit --target Läufen funktioniert, sollte es auch mit Nicht-Ziel-Läufen funktionieren. AFAICS, letzteres ist ein neues Verhalten.

Ich denke, selbst wenn --target nicht sehr lange überlebt, kann es sinnvoll sein, ein --no-replace , das unabhängig von --target funktioniert. Ich weiß jedoch nicht, ob jemand diese Funktionalität ohne --target haben möchte.

PS: Entschuldigung für das Vermüllen so vieler Inline-Monospace-Blöcke.

Ich denke nicht, dass --target (und insbesondere sein aktuelles Standardverhalten) wichtig genug ist, um das Hinzufügen eines neuen Flags zu rechtfertigen, nur um es beizubehalten. IMO, wir wechseln einfach --target zum Ersetzen standardmäßig und verlieren die Möglichkeit, nur neue Dateien hinzuzufügen (was sowieso wahrscheinlich zu kaputten Setups führt).

Ein bereits installiertes Paket nicht zu aktualisieren _ist_ ein sicherer Vorgang, aber --target tut dies nicht, da es keinen Zugriff auf Informationen über die "aktuell installierten" Informationen hat.

Ändern Sie also das Verhalten von --target , um sich nicht mehr um bereits vorhandene Verzeichnisse zu kümmern und sie einfach zu ersetzen und dabei eine Nachricht auszugeben? Auch kein Nachrichtendruck?

Hm, warte. Entschuldigung, Ihre Beschreibung hat mich verwirrt (und ich bin nicht zurückgegangen, um die Dokumente zu überprüfen). Es tut uns leid. Mein obiger Kommentar war falsch. Was ich hätte sagen sollen:

Derzeit ersetzt --target keine Sachen. Das ist notwendig, da es nicht sicher deinstalliert/aktualisiert werden kann (es gibt keine installierte Paketdatenbank mit --target und keine Garantie, dass eine neue Version keinen anderen Satz von Dateien hat als die vorherige Version). Das aktuelle Verhalten von --upgrade --target ist (AFAICT) unsicher.

Also sollte --target sein aktuelles Verhalten beibehalten. Dies macht es inkonsistent mit der neuen Installation, aber das ist in Ordnung, es ist für einen völlig anderen Anwendungsfall. Ich habe kein Problem damit, dass --upgrade entfernt wird, und als Ergebnis verliert --target diese Fähigkeit - es ist sowieso eine unsichere Operation.

Da ich mit der Änderung des Standardverhaltens von --target nicht einverstanden bin, besteht keine Notwendigkeit für ein --no-replace Flag.

Ich bin mir nicht sicher, was Sie damit meinen, dass --target von --upgrade abhängig ist.

Es könnte der Diskussion helfen, den aktuellen Hilfetext von --target zu lesen.

""" Pakete installieren in

. Standardmäßig werden vorhandene Dateien/Ordner in nicht ersetzt. Verwenden Sie --upgrade, um vorhandene Pakete in zu ersetzenmit neuen Versionen. """

Ich bin mir nicht sicher, was Sie mit --target mit einer Abhängigkeit von --upgrade meinen.

Um das Ersetzen vorhandener Inhalte zu ermöglichen.

Da ich mit der Änderung des Standardverhaltens von --target nicht einverstanden bin, ist das Flag --no-replace nicht erforderlich.

Wenn das Verhalten von --target nicht geändert wird, würde dies bedeuten, dass das Flag --upgrade mindestens so lange bestehen bleiben muss, wie --target ist.


Ich möchte den Verweis auf --upgrade in der Hilfe von --target überflüssig machen.

Okay, lass mich umformulieren. Das Verhalten von --target sollte (IMO) nur in einer Hinsicht geändert werden, nämlich dass --upgrade (und das dadurch ermöglichte Verhalten) entfernt werden sollte.

Wenn jemand einen Anwendungsfall für --upgrade demonstrieren kann (vorausgesetzt, dass dies möglicherweise Dinge kaputt macht), bin ich bereit, diese Position zu überprüfen, aber ich denke nicht, dass es sich lohnt, es "nur für den Fall" zu behalten.

Das Verhalten von --target sollte (IMO) nur in einer Hinsicht geändert werden, nämlich dass --upgrade (und das damit aktivierte Verhalten) entfernt werden sollte.

Okay. Das macht es klar.

Wenn jemand einen Anwendungsfall für --upgrade . demonstrieren kann

Nicht ich.

Das hört sich für mich auch gut an. Es kommt mir wie eine böse Warze vor, dass --target --upgrade für diesen Zweck verwendet hat.

Ich denke, wir sollten die weitere Diskussion auf #3806 verschieben, um zu vermeiden, dass 2 Kommentarthreads mit gleichzeitigen Diskussionen über dasselbe Thema vorhanden sind.

Wow, dieser Thread ist kritisch geworden. Lassen Sie mich nur meinen starken Widerstand gegen die Änderung der Bedeutung von -U hinzufügen. Es besteht absolut keine Notwendigkeit, das Muskelgedächtnis unserer Benutzer zu brechen - wir können eine neue Option hinzufügen, wenn wir nicht-rekursive Upgrades benötigen. Was ist der Anwendungsfall für nicht-rekursive Upgrades _anders als_ 'pip install named-thing' ?

Ich denke beispielsweise, dass es in Ordnung ist zu sagen, dass explizit benannte Distributionen implizit aktualisiert werden und -U, falls bereitgestellt, ein vollständig rekursives Upgrade verursacht. in allen Fällen ohne --ignore-dependencies prüft pip rekursiv auf Zufriedenheit.

@rbtcollins : "Das Muskelgedächtnis unserer Benutzer zu brechen" scheint ein bisschen stark zu sein -- WRT -U , die Änderungen im aktuellen Vorschlag wären: (a) pip install -U foo ist immer noch legal und aktualisiert immer noch foo , aber jetzt nicht-rekursiv, (b) verliert es das spezielle Verhalten, bei dem die Kombination von -U plus --target "alle vorhandenen Dateien überschreiben" bedeutet. Ich vermute, dass die letztere Änderung Sie nicht allzu sehr beunruhigt, da Sie kürzlich versucht haben, --target und dass die meisten Benutzer kein Muskelgedächtnis für -U --target (hoffe ich! ). Sie meinen also, dass Sie es vorziehen, dass pip install foo einen nicht-rekursiven Upstall von foo und pip install -U foo einen rekursiven Upstall von foo ?

Ich könnte damit leben, insbesondere als Übergangszustand, in dem wir gleichzeitig -U ablehnen, aber es hat definitiv Nachteile:

  • AFAICT rekursives Upgrade ist eigentlich nie das, was jemand will? Es hat sehr gravierende Nachteile, und selbst in den Fällen, in denen es sinnvoll ist, scheint es daran zu liegen, dass die Semantik des Codes ("Paket und seine Abhängigkeiten") versehentlich mit der Semantik des Benutzers übereinstimmt ("dieses Paket + die zugehörigen Pakete, die in meinem Kopf denke ich an den gemeinsamen Versand als Einheit"). Siehe meinen Post-Upthread -- _In vielen Fällen ist es nicht wirklich sinnvoll, einer bestimmten Abhängigkeit eine Abhängigkeit zuzuweisen..._ . Vielleicht denken Benutzer manchmal "Ich möchte mein Pyramid-Ökosystem aktualisieren", aber selbst wenn sie dies tun, erwarten sie nicht, dass dies die Setuptools aktualisiert - aber das ist es, was rekursive Upgrades tun. Auf lange Sicht scheint mir ein rekursives Upgrade also einfach das Falsche – vielleicht gibt es hier einen gültigen Anwendungsfall, aber wenn ja, sollten wir herausfinden, wie wir diesen Anwendungsfall direkt ansprechen können.
  • Selbst wenn ein rekursiver Upgrade-Switch benötigt wird, ist es auf keinen Fall die richtige langfristige Lösung, diesen Switch --upgrade zu schreiben. Müssen wir neuen Benutzern wirklich erklären, dass der richtige Weg, um ein Paket zu aktualisieren, darin besteht, den --upgrade Schalter _auszulassen_?
  • Es macht den Leuten, die Dokumentation schreiben, auch das Leben ziemlich schwer, wenn der "beste verfügbare Upgrade-Befehl" auf pip >= 9 pip install foo , aber auf pip < 9 ist es pip install -U foo . Ich möchte die Leute nicht zu rekursiven Upgrades anleiten, aber ich möchte sie auch nicht mit Pip-Versionsnummern verwechseln. Was füge ich also in mein Tutorial ein? OTOH Wenn pip >= 9 macht pip install und pip install -U äquivalent, dann bleibt der Rat, pip install -U foo korrekt, nur ein bisschen überflüssig.
  • Außerdem ist die Unterstützung dieser beiden verschiedenen Modi kompliziert und nervig -- pip bereits viel zu viele Modi, die kompliziert, schlecht dokumentiert, schwer zu warten sind und nicht ganz das tun, was irgendjemand will. Wenn wir es vereinfachen können, indem wir eines davon loswerden, dann ist das _großartig_, und bisher waren die Argumente für rekursive Upgrades sehr dünn gesät. AFAICT kein anderer Paketmanager unterstützt dies und niemand beschwert sich. Sogar Sie scheinen Ihr Argument (bisher) auf "dieses Ding existiert und wir sollten das nicht ändern" zu stützen, anstatt auf "dieses Ding ist tatsächlich nützlich und was unsere Benutzer wollen" ...

Also wäre es mir viel lieber, wenn wir weitermachen und pip install foo / pip install --upgrade foo bringen, das Offensichtliche zu tun, was alle anderen tun. Ich denke, die Muskelerinnerungen der meisten Benutzer werden angenehm überrascht sein, wenn sie anfangen, das zu bekommen, was sie sich erhofft haben :-).

Der Kommentar von

Ich denke, ich sollte von hier aus auf https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 verlinken. Dies ist der letzte "Vorschlag", den ich geschrieben habe, der aus der Diskussion zu diesem Thema hervorgegangen ist. Es gibt einen Abschnitt über den "Aktuellen Stand der Dinge ", den

@njs - Ich denke nicht, dass es zu stark ist: Im

Das Verhalten mit --target ist in der Tat nicht der Fall, worüber ich mir Sorgen mache.

FWIW Ich stimme Ihrer Analyse über das, was die Leute wollen/nicht wollen, nicht zu. Die meisten Projekte testen nur eine kleine Anzahl von Permutationen von Versionen: neueste-mit-neueste + neueste-mit-stable, wenn eine stabile Version vorhanden ist. Alles zu aktualisieren ist tatsächlich sicherer, als nur die benannte Komponente zu aktualisieren, da die niedrigeren Versionsspezifizierer normalerweise falsch sind. Siehe Nr. 3188 für eine Verbesserung, die das Testen niedrigerer Versionsgrenzen viel einfacher machen würde. Ich habe aufgehört zu zählen, wie oft ich das Problem der Leute "behoben" habe, indem ich ihnen gesagt habe, "pip install -U" zu verwenden: Sie hatten ein Paket mit einem falschen unteren Minimum.

Die eigentliche zugrunde liegende Sache, die Ihr "Das ist falsch" antreibt, ist, soweit ich das beurteilen kann, #2687 - dort kann Pip das Richtige tun.

Darüber hinaus ist das _Allerletzte_, das wir wollen, dass pycrypto und seine Freunde monate- oder jahrelang nicht aktualisiert bleiben, weil die Leute nicht wissen, dass sie etwas Besonderes tun müssen, um eine aktuelle sichere Software zu haben.

Wenn Leute sehr komplexe Venvs ausführen, entscheiden sie sich für die Komplexität - die häufigsten Fälle sind a) vollständige Python-Installationen und b) dedizierte Venvs. Wir sollten alle so weit wie möglich auf b lenken, weil es von Natur aus zuverlässiger ist, und das verstärkt mein Argument, dass der Standard sein sollte, sicher zu sein und so nah wie möglich an dem zu arbeiten, was der Upstream wie möglich getestet hat.

wrt Paketmanager - 'apt install X' wird nie upstall - es wird nur installiert. 'apt upgrade' ist global - es aktualisiert alles'. DNF ist ähnlich AIUI. Ich habe das Tool von suse nicht untersucht, aber ich würde ein ähnliches Verhalten erwarten, da die Distros abgeflacht sind, es kann nur eine Idiom-Distribution geben.

Vielleicht sollten wir dafür eine Diskussion über eine höhere Bandbreite führen? Es scheint IMO in eine ziemlich gefährliche Richtung zu weisen.

@pradyunsg Ihre Behauptung über den aktuellen Status von Pip in https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 ist sachlich falsch: Es gibt bereits einen --no-dependencies-Schalter, der den rekursiven/nicht-rekursiven Fall abdeckt. 'pip install -U foo --no-deps && pip install foo' sollte semantisch äquivalent zu 'upstall named Packages by default' sein - und damit bin ich einverstanden.

Nein tl; dr . Lies es.


@rbtcollins

Ihre Behauptung über den aktuellen Status von Pip in https://gist.github.com/pradyunsg/4c9db6a212239fee69b429c96cdc3d73 ist sachlich falsch: Es gibt bereits einen Schalter --no-dependencies, der den rekursiven/nicht-rekursiven Fall abdeckt

Ich habe nie behauptet, dass pip nicht die Möglichkeit bietet, nicht eifrige Upgrades durchzuführen, oder dass ein --no-deps in der Zuschreibung oder (in meiner Erinnerung) irgendwo anders fehlt. Welchen Teil meiner "Behauptung zum aktuellen Status von Pip" halten Sie für "tatsächlich falsch"?

Erwägen Sie, diesen Abschnitt noch einmal zu lesen und in einem Kommentar zum Kern (nicht hier, es wird Rauschen) explizit auf "tatsächlich falsche" Punkte hinzuweisen, damit ich sie korrigieren kann.

Das ist der einzige Grund, install -U jemals (heute) auszuführen, und so bricht es seinen primären Anwendungsfall.

Niemand geht herum, um die Welt zu zerstören.

  • pip install -U pkg wird weiterhin pkg aktualisieren, was die meisten Leute wollen und interessieren. Es ist, was mit den geänderten Abhängigkeiten passiert.
  • Die -U/--upgrade (jetzt keine Operation) werden bleiben, bis sie das Gefühl haben, dass sie nicht mehr benötigt werden, weil alle weitergezogen sind.

FWIW Ich stimme Ihrer Analyse über das, was die Leute wollen/nicht wollen, nicht zu. Die meisten Projekte testen nur eine kleine Anzahl von Permutationen von Versionen: neueste-mit-neueste + neueste-mit-stable, wenn eine stabile Version vorhanden ist.

Wenn der Paketentwickler schlechte Metadaten bereitstellt, ist es kein _falsches_ Verhalten von pip, dass es deswegen die Umgebung des Benutzers beschädigt hat. Es liegt in der Verantwortung des Paketentwicklers, die richtigen Versionseinschränkungen bereitzustellen. Ich stimme zu, dass #3188 dem Paketentwickler dabei helfen würde.

Ich denke nicht, dass es falsch ist, von den Leuten zu erwarten, dass sie die Metadaten verbessern, die sie PyPI (und damit auch Pip) bereitstellen.

Das Allerletzte, was wir wollen, ist, dass pycrypto und seine Freunde monate- oder jahrelang nicht aktualisiert werden, weil die Leute nicht wissen, dass sie etwas Besonderes tun müssen, um eine aktuelle sichere Software zu haben.

Einverstanden. Ich denke, wenn es sich um sichere Software handelt, sollte den Sicherheitspaketen besondere Aufmerksamkeit geschenkt werden. Darüber hinaus werden alle Pakete, die bei Upgrades übersprungen werden, explizit als solche aufgeführt. Jemand, der sich die Ausgabe ansieht, würde also wissen, was passiert ist, und entscheiden, ob er Maßnahmen ergreifen möchte.

Wenn Ihnen ein Sicherheitspaket am Herzen liegt, können Sie es nach dieser Änderung einfach direkt in der CLI erwähnen, was Ihre Absichten deutlicher und klarer macht. Ich bevorzuge es so. Diese Änderung würde Sie dazu zwingen, zu erwähnen, welche Pakete Sie auf dem neuesten Stand halten möchten.

"explizit ist besser als implizit"

Wenn Leute sehr komplexe Venvs ausführen, entscheiden sie sich für die Komplexität - die häufigsten Fälle sind a) vollständige Python-Installationen und b) dedizierte Venvs. Wir sollten alle so weit wie möglich auf b lenken, weil es von Natur aus zuverlässiger ist, und das verstärkt mein Argument, dass der Standard sein sollte, sicher zu sein und so nah wie möglich an dem zu arbeiten, was der Upstream wie möglich getestet hat.

Ich stimme zu, dass jeder häufiger virtuelle Umgebungen verwenden sollte. Ich stimme auch zu, dass es auch günstig ist, so nah wie möglich am Fluss zu laufen. Ich finde es ironisch, dass Sie das Wort "sicher" verwenden, um ein Verhalten zu verteidigen, das still (und oft) den Abhängigkeitsgraphen durchbricht.

'pip install -U foo --no-deps && pip install foo' sollte semantisch äquivalent zu 'standardmäßig benannte Pakete upstall' sein.

Es ist. Die ganze Motivation dieser PR besteht darin, pip install -U foo --no-deps && pip install foo als pip install foo bereitzustellen, weil das Verhalten, das jeder die meiste Zeit wünscht, direkt verfügbar sein sollte. Es wurde diskutiert und entschieden, dass es besser ist, keine Möglichkeit zu bieten, eifrige Upgrades durchzuführen.

Die eigentliche zugrunde liegende Sache, die Ihr "Das ist falsch" antreibt, ist, soweit ich das beurteilen kann, #2687 - dort kann Pip das Richtige tun.

In früheren Diskussionen (#59, bei pypa-dev) wurde festgestellt, dass das Verhalten in #2687 nicht behoben werden kann, bis #988 landet, was einige Zeit dauern kann , und dieses Verhalten wird als die sicherere Mitte angesehen -Erde in der Zwischenzeit.

Jedes Mal, wenn heute jemand pip install -U pkg , riskiert er, ein anderes Paket in seiner Umgebung zu beschädigen. Obwohl auch nach dieser PR das gleiche Risiko bestehen bleibt, wird die Häufigkeit, mit der die Aktionen von pip zu einer Umweltzerstörung führen, reduziert.

Ich bin damit zufrieden

Es ist in Ordnung, wenn Sie es als Opt-in-Verhalten haben, nicht eifrige Upgrades durchzuführen. Ich bin nicht damit einverstanden, die Umgebung des Benutzers standardmäßig stillschweigend zu unterbrechen. Das ist es, was eifrige Upgrades tun, wie ich es sehe, mit #2687 ungelöst.

Es wäre besser, die Umgebung des Benutzers nicht lautlos zu durchbrechen. Diese Änderung ist das Beste, was wir in Anbetracht der begrenzten Entwicklungszeit tun können, die direkt in Pip investiert wird.

Vielleicht sollten wir dafür eine Diskussion über eine höhere Bandbreite führen?

Das ist die Idee hinter dem "Shout-Out" auf distutils-sig.

(gelöscht, da im falschen Thread gepostet)

Ihr Argument ist, dass weniger Leute geschädigt werden, wenn Abhängigkeiten nicht aktualisiert werden, die nicht /müssen/ geändert werden müssen, wenn jemand -U geliefert hat. Mein Argument ist, dass mehr Menschen zu Schaden kommen:

  • es ändert sich von standardmäßig sicher zu standardmäßig unsicher. Es kann nicht davon ausgegangen werden, dass Benutzer qualifiziert oder daran interessiert sind, festzustellen, welche Pakete sicherheitsrelevant sind und welche nicht. Ein UX-Modell, das davon abhängt, dass Benutzer diese zusätzliche Arbeit leisten, ist aktiv schädlich IMO
  • es ändert sich von ideal in den empfohlenen Fällen zu konservativ im pathologischen Fall und schädlich im empfohlenen Fall

Angesichts dieser beiden Möglichkeiten:
A – Benutzer sind anfällig für Sicherheitsprobleme und wissen nicht, dass sie es sind
B - Benutzer erhalten gelegentlich defekte Umgebungen aufgrund von #2687

Ich sehe nicht, wie wir irgend etwas anderes als B wählen können. Es wäre völlig unverantwortlich, etwas anderes zu tun.

Es tut mir leid, dass ich etwas holprige Antworten gebe, aber eine andere Sache, die ich hier beobachte, ist, dass wir die Komplexität erhöhen - Fracht zum Beispiel hat nicht annähernd die hier vorgeschlagene feinkörnige Kontrolle. Das liegt vor allem daran, dass die Sprache bessere Primitive für die Isolierung hat - wie Javascript und Java rust mit mehreren Versionen eines Pakets im Abhängigkeitssatz umgehen können -, wodurch unsere Auflösung dort fast völlig irrelevant ist, _außer_ wenn die Leute auf nur eine Version reduzieren möchten , während wir keine Wahl haben. Aber ich denke, wir müssen wirklich starke Gründe für die Erhöhung der Komplexität suchen – nicht nur im Kern von pip, sondern im Benutzermodell. Die Grunderwartung von PyPI ist, dass alle die ganze Zeit zusammenarbeiten; Standardmäßig nicht zu aktualisieren ist so ziemlich das Gegenteil davon.

Also - werden unsere Erwartungen gebrochen oder reagieren wir nur auf Fehler in Pip, wo genügend Informationen vorhanden sind, um zumindest einen besseren Job zu machen?

Reagieren wir nur auf Fehler in PIP, wo genügend Informationen vorhanden sind, um zumindest einen besseren Job zu machen?

Dies. Wir können definitiv _viel_ besser mit den Informationen, die wir haben, machen. Aber es ist traurig, dass wir das nicht tun. Dafür gibt es auch Gründe, aber das ist nicht der Hauptpunkt dieser Diskussion.

Angesichts dieser beiden Möglichkeiten:
A – Benutzer sind anfällig für Sicherheitsprobleme und wissen nicht, dass sie es sind
B - Benutzer erhalten gelegentlich defekte Umgebungen aufgrund von #2687

Ich finde sie gleich schlimm. Die Sache ist die, der Benutzer kann sehen, dass sein Sicherheitspaket nicht aktualisiert wurde und er kann (und sollte) sich für dieses Upgrade anmelden. Das ist etwas besser als der Status Quo IMO.

Ich stimme nicht zu, dass sie gleich schlecht sind.

  • Benutzer in automatisierten Umgebungen können die Ausgabe nicht sehen oder überprüfen, sodass sie nicht wissen, dass ein Paket nicht aktualisiert wurde.
  • Benutzer, die sehen, wissen nicht, dass ein bestimmtes Paket sicherheitsrelevant ist.

Ihre vorgeschlagene Änderung verschiebt Pip von einem Modell für die sichere Sache zu einer Überprüfung-jeder-Aufrufe-sorgfältig-weil-es-möglicherweise-stillschweigend-das-Falsche-gemacht-haben. Ich würde erwarten, dass dies für einen Systemadministrator unglaublich besorgniserregend ist [was ich war, also ist dies keine müßige Spekulation]. Wir haben jedoch keine ausführlich definierten Personas, auf die wir hinweisen können, damit dies von neuen Mitwirkenden bei pip leicht verinnerlicht werden kann.

Es besteht jedoch die Gefahr, dass ich in diesem Konversationsmuster ausbrennt, also melde ich das Problem ab und schalte es stumm; mein Angebot für Konversationen mit höherer Bandbreite - was die Sig-Liste nicht ist - bleibt offen, wenn das nützlich ist - @njsmith und @dstufft können mich in Hangouts oder IRC oder jedem gewünschten Echtzeitmedium erreichen.

Ich warte immer noch auf @pfmoore https://github.com/pfmoore oder @njsmith
https://github.com/njsmith gibt mir grünes Licht, dass diese PR in Ordnung ist
und wir können das gleiche auf distutils-sig für Kommentare von einem größeren ankündigen
Publikum.

Entschuldigung, ich hatte nicht gemerkt, dass Sie sich zurückgehalten haben. Ja, bitte mach weiter und
bekannt geben. Die PR muss natürlich als diese Diskussionen aktualisiert werden
Fortschritt, aber es ist sicherlich ein guter Ausgangspunkt für diesen Prozess.

@rbtcollins Ich wollte nicht zu aufdringlich sein. Das tut mir leid.

Konversation mit höherer Bandbreite

Ich habe es nicht als Echtzeit-Gespräch interpretiert. :Schweiß:

Do-the-Safe-Thing-Modell zu einer Überprüfung-jeden-Aufrufe-sorgfältig-weil-es-kann-das-falsche-Ding-im-Still-gemacht-haben

Ich verstehe, was Sie zu den möglichen sicherheitsbezogenen Auswirkungen dieser Änderung sagen möchten. Ich habe kein besonders starkes Verständnis für dieses Thema und die damit verbundenen Nuancen, um eine angemessene Diskussion darüber zu führen.

Ich werde jede weitere Diskussion gerne an die Kernentwickler von pip weiterleiten.


Nun, ich denke, dass beide Verhaltensweisen (das aktuelle von Pip und das vorgeschlagene) nicht ideal sind. Ich werde meine Position ändern, um beides nicht zu befürworten. Ich schreibe diese Mail an distutils-sig.

Außerdem ist das _allerletzte, was wir wollen, dass pycrypto und seine Freunde es tun
Bleiben Sie monate- oder jahrelang ohne Upgrade, weil die Leute nicht wissen, dass sie es müssen
etwas Besonderes tun, um eine aktuelle sichere Software zu haben.

Wenn Sie sagen, dass ein Benutzer pip install --upgrade django tut
(wo django beispielsweise von pycrypto abhängt) wird derzeit pycrypto aktualisiert,
und in Zukunft nicht, dann ja, das ist eine Änderung (und vereinbart, es könnte
führen dazu, dass pycrypto eine ältere Version ist).

Es gab in letzter Zeit eher zu viele spaltende Sicherheitsdiskussionen, und
Ich möchte nicht die Ursache dafür sein, dass ein anderer anfängt. Also alles was ich sagen werde
Hier ist, dass es einen Kompromiss gibt, die Krypto-Software auf dem neuesten Stand zu halten
im Vergleich zum Brechen von Paket X durch Upgrade einer Krypto-(oder einer anderen!)-Abhängigkeit auf a
Version, die X nicht als Teil eines unabhängigen pip install Y . Mein
persönliche Präferenz ist für den Ansatz dieser PR (aber siehe unten), aber
Ich erkenne das Problem an. Eine Frage - was tun Linux-Paketmanager?
tun? Würde apt-get install python-django ein bereits installiertes Upgrade aktualisieren?
und kompatibel python-pycrypto ? Nach etabliertem Linux-Paket
Manageransätze würden gut zur Grundlage des Rests dieser PR passen).

Beachten Sie, dass "meine Sachen auf dem neuesten Stand halten" (das Äquivalent von apt-get upgrade , schätze ich) das ist, wofür pip upgrade-all gedacht war (siehe

59). Das ist nicht Teil dieses Vorschlags. Meine bevorzugte Antwort auf Ihre

Die obige Sorge wäre zu sagen "der richtige Weg, um Sicherheitspakete aufrechtzuerhalten".
bisher ist pip upgrade-all " - Sicherheits-Upgrades _sollten nicht_
warten Sie, bis ein anderes Paket aktualisiert wird. (Es ist genauso wahr, das zu sagen
Sie sollten nicht warten, bis der Benutzer sein gesamtes System aktualisiert, also die "echten"
Antwort ist pip install [-U] pycrypto aber ich denke, wir können uns darauf einigen
die Trägheit des Benutzers ist nicht immer realistisch). Vielleicht der
Ist oben ein Argument für diesen Unterbefehl? Aber ich bin mir nicht sicher, ob es
ohne einen geeigneten Dependency Resolver eine akzeptable Arbeit erledigen kann.

Beachten Sie auch, dass Pip in einer idealen Welt niemals etwas kaputt machen würde
eine Verbesserung. Leider ist das nicht der Fall, bis wir einen vollständigen Abhängigkeitslöser haben
Fall. Ich glaube, wir haben Fälle von solchen Brüchen gemeldet. Bruch sollte
selten sein - aber seien wir fair, Sicherheits-Exploits sollten es auch sein. Wir diskutieren
Szenarien mit geringer Wahrscheinlichkeit (aber potenziell hoher Auswirkung) hier, und es ist
nie leicht zu beurteilen (wenn es so wäre, würde niemand jemals Lotto kaufen)
Karten :-))

Ich habe kein besonders starkes Verständnis für dieses Thema und die damit verbundenen Nuancen, um eine angemessene Diskussion darüber zu führen.

Ich auch nicht. Ich denke, @rbtcollins hat einen wichtigen Punkt @dstufft als die einzige Person, die ich kenne mit ausreichendem Verständnis von Pip und Sicherheit, um hier eine fundierte Entscheidung zu treffen ...

@pfmoore ja, das sage ich, und ich starre mit Entsetzen auf das Fass von Millionen von Umgebungen, die keine Upgrades für solche Bibliotheken mehr erhalten.

Ich stimme zu, dass ein Befehl zum Ausführen eines umgebungsweiten Upgrades hilfreich wäre.

bzgl. des Resolver-Aspekts - Bruch wird auch bei einem Resolver immer passieren: Der Resolver ist nicht die Ursache für die meisten Brüche, die ich sehe, eher zufällige Fehler. Ja, wir brauchen es, aber es ist kein Allheilmittel.

@pradyunsg Sie müssen sich nicht entschuldigen - Sie haben nichts falsch gemacht; Ich engagierte mich, während ich müde war und war gestresst bei der Vorstellung, dass etwas, das ich für eine schlechte Wahl halte, in den Meister gedrängt würde, wenn ich nicht sofort darauf Halt fand.

Ich starre nicht mehr auf das Fass von Millionen von Umgebungen
Upgrades für solche Bibliotheken mit Entsetzen erhalten.

Dies wäre etwas anderes als die aktuelle Änderung, und ich habe es nicht
überhaupt durchdacht, aber ich frage mich, ob hier noch Pakete benötigt werden
(oder vielleicht einzelne Veröffentlichungen) als "kritisch" gekennzeichnet werden, was bedeutet, dass
pip sollte immer versuchen, diese Pakete zu aktualisieren, wenn etwas aktualisiert wird, das
hängt von ihnen ab - im Wesentlichen eine feinkörnigere Opt-in-Version von Eifer
Aktualisierung. Projekte wie pycrypto könnten sich dann als kritisch bezeichnen.

Ein solcher Mechanismus kann missbraucht werden, aber wäre dies hilfreich?

Ein solcher Mechanismus kann missbraucht werden, aber wäre dies hilfreich?

Bitte nicht. Es ist eine schlechte Idee, so etwas in einem weitgehend unmoderierten Index wie PyPI zu haben. Abgesehen von der offensichtlichen Möglichkeit des Missbrauchs ist dies ein zusätzliches Verhalten, von dem der Benutzer möglicherweise überrascht wird. Ich denke, es gibt einfach bessere Möglichkeiten, mit einem solchen Problem umzugehen; Es ist besser, dies an die Endbenutzer zu delegieren, um zu entscheiden, was ihrer Meinung nach kritisch ist.

@rbtcollins Ich hatte das Gefühl, dass ich der Grund war, warum du das Gefühl

Ich denke @dstufft hat schon genug Sachen auf seinem Teller. Also, FWIW, ich werde darlegen, was ich über die Sicherheitsfront von nicht eifrigen Upgrades als Standard denke. Ansonsten lerne ich etwas Neues.

Ich glaube nicht, dass jemand pip install --upgrade in einer Produktionsumgebung ohne fixierte Anforderungen/Einschränkungen ausführt. Ich könnte mich da irren, aber das sollten sie wirklich nicht. Wenn sie das tun, öffnen sie sich bereits heute wie heute für die Zerstörung ihrer Produktionsumgebung. Nach dieser Änderung haben sie immer noch dieses Risiko (reduziert, aber vorhanden) und zusätzlich das Risiko, nicht über die neuesten Sicherheits-Upgrades zu verfügen. Wirklich, indem sie ihre Abhängigkeiten nicht festnageln, würde ich sagen, dass sie sich für eine Sicherheitslücke entschieden haben. Würden Sie dem zustimmen?

Für mich sind die einzigen Leute, die pip install --upgrade ausführen, diejenigen, die dies auf ihren lokalen Computern tun, entweder während der Entwicklung einer Anwendung oder als Endbenutzer einer Bibliothek. Wie sehr sie das beeinflusst, weiß ich nicht. Ich bin sowieso kein informierter Mensch zu diesem Thema.


Ehrlich gesagt, je mehr ich darüber nachdenke, desto mehr möchte ich mich hinsetzen und einen SAT-Solver in reinem Python für Pip schreiben.

Okay, ich ignoriere diese Diskussion für ein paar Tage, sie scheint sowohl auf der Sig als auch hier explodiert zu sein :)

Ich habe versucht, zu lesen, was in diesem Thread passiert ist, aber er ist lang und informationsdicht, sodass ich etwas übersehen könnte, aber Sie werden gleich eine Wand aus Wörtern bekommen.


Ich glaube nicht, dass es ganz fair ist zu sagen, dass das derzeitige Verhalten von pip install -U <foo> die Sicherheit der Menschen auf breiter Front erhöht. Ja, ich kann leicht auf einige Projekte wie PyCrypto oder Kryptographie hinweisen, bei denen Regressionen selten sind (insbesondere Sicherheitsregressionen) und neue Releases im Allgemeinen Verbesserungen der Sicherheit beinhalten. Ich denke, die Konzentration auf diese übersieht andere Fälle, beispielsweise den Fall, in dem eine neue Version von etwas auf PyPI einen Rückgang der Sicherheit verursacht hat. Ich denke, es gibt jedoch noch zwei andere Fälle, die beide darauf hinauslaufen können, dass ein Upgrade die Sicherheit überhaupt nicht beeinträchtigt oder nicht, sich jedoch darin unterscheidet, ob ein Upgrade für sie in Ordnung ist oder nicht.

Insgesamt denke ich nicht, dass rekursive Upgrades ein guter Sicherheitsmechanismus sind, und wenn eines unserer Ziele darin besteht, zu verhindern, dass Leute alte, unsichere Versionen von Software ausführen (und ich denke, es sollte ein Ziel sein), als ich denke, der Weg, um das zu erreichen Das heißt nicht, uns vom Verhalten von Upgrades abzuhängen (und nur zu beten und zu hoffen, dass sie zufällig in einiger Zeit ein Update ausführen), sondern stattdessen Zeit für eine dedizierte Lösung des Problems zu verwenden. Dies kann etwa pip list -o aber das explizit auf Sicherheitsprobleme prüft, kann den gesamten installierten Satz von Paketen gegen PyPI überprüfen, um zu sehen, ob irgendwelche Sicherheitsprobleme mit einem von ihnen bekannt sind, oder es kann dauern einige ganz andere Formate. Ich halte es jedoch für wichtig, dass dies nicht an eine halb verwandte Funktionalität gebunden ist und tatsächlich die gesamte Umgebung abdeckt und nicht nur das, was der Benutzer gerade verwendet. Wenn jemand einmal pip install requests[security] und dann von da an pip install -U requests – dann werden wir die Updates für pyopenssl und cryptogaphy komplett verpassen und so weiter wenn wir uns nur auf rekursive Upgrades verlassen.

Um die Sicherheitsbedenken für einen Moment beiseite zu schieben, müssen wir meiner Meinung nach einen Blick darauf werfen, welche Verhaltensweisen den Menschen am ehesten das geben, was sie wollen. Leider vermute ich, dass es bei einem so großen Ökosystem und mit so unterschiedlichen Anwendungsfällen wie Python keine einzige Antwort auf "was die Leute wollen" gibt. Hier werden einige miteinander verbundene Verhaltensweisen besprochen, also lassen Sie uns sie nacheinander angehen.

Für pip install --upgrade <foo> haben wir Beweise dafür, dass unser aktuelles Verhalten aktiv schädlich ist, so sehr, dass Projekte alles daran setzen, zu lügen, um zu verhindern, dass dieses Verhalten ausgelöst wird. Ich denke, wir sind uns alle einig, dass etwas, bei dem die Leute das Bedürfnis haben, aktiv zu untergraben (nicht nur in ihren eigenen Projekten, sondern auch für andere Projekte), wahrscheinlich einige Verfeinerungen der tatsächlichen Funktionsweise erfordert. In diesem Fall besteht die einzige wirkliche Lösung darin, ein Upgrade (oder Downgrade!) nach Möglichkeit zu vermeiden und die bereits installierte Version zu bevorzugen, _es sei denn_ der Benutzer hat ausdrücklich darum gebeten, _oder_ wir die Versionsbeschränkungen sonst nicht erfüllen können . Ich kann keine andere vernünftige Möglichkeit sehen, dies zu implementieren, die nicht versehentlich mehr als 30-minütige Builds auslöst, die möglicherweise zu einer Version führen, die für die vorliegende Aufgabe weniger geeignet ist (kein optimiertes BLAS oder so).

Sich dafür einzusetzen, dass das derzeitige Verhalten von pip install --upgrade so belassen wird, wie es ist, spricht sich im Wesentlichen gegen Projekte aus, die von numpy abhängen, weil sie ehrlich sind, ob sie von numpy abhängen oder nicht. Wenn jemand einen anderen Vorschlag hat, wie wir das numpy-Problem [1] lösen könnten, dann denke ich, dass er ihn ansprechen sollte.

Ich weiß, dass ein Vorschlag darin bestand, ein --non-recursive-upgrade Flag oder eine Art --upgrade-strategy Flag hinzuzufügen, aber ich denke, dass diese Ideen hauptsächlich nur dazu dienen, das mentale Modell zu komplizieren, das die Leute von Pip haben. Für die überwiegende Mehrheit der Pakete (insbesondere reine Python-Pakete, die keine sicherheitskritische Rolle spielen) spielt es keine große Rolle, ob wir sie aktualisieren oder nicht installierte Version (es sei denn, die Person findet einen Grund, eine Funktion oder einen Fehler, um _dieses_ Paket explizit zu aktualisieren). Wir leben hier jedoch in den Grenzfällen und ich sehe nur die beiden, die wirklich wichtig sind, schwer zu aktualisierende Pakete und sicherheitskritische Pakete, und wie ich oben erwähnt habe, denke ich, dass wir uns Sorgen machen werden, die Leute zu gewährleisten Sicherheits-Upgrades bekommen brauchen wir dafür einen echten Mechanismus, keine halbherzige Hoffnung, dass ein wichtiges Upgrade irgendwann in einem rekursiven Upgrade hängen geblieben ist. Angesichts der Tatsache, dass wir dedizierte Unterstützung für sicherheitsrelevante Themen benötigen, wird dies für die meisten Pakete keine Rolle spielen und für den schwer zu aktualisierenden Fall gibt es nur eine Antwort Begründung der laufenden Kosten für die Aufrechterhaltung einer ganzen Option dafür [2]. Ich denke auch, dass der konservativere Ansatz der offensichtlichste sein muss oder wir die Dinge nicht wirklich für die schwer zu aktualisierende Masse lösen. Wenn wir also eine neue Option hinzufügen würden, würden wir das Verhalten trotzdem ändern wollen von --upgrade standardmäßig und fügen Sie eine explizite Option hinzu, um den weniger konversativen/sicheren Ansatz für Upgrades zu erhalten.

Ich glaube nicht, dass wir einem Paket erlauben sollten, sich selbst für eifrige (oder nicht eifrige) Upgrades zu markieren. Ich denke, dies muss bei allen Paketen konsistent sein, damit Endbenutzer hoffen können, ein vernünftiges mentales Modell davon zu haben, was pip mit ihrem System anstellen wird, wenn sie einen Befehl ausführen. Abgesehen davon könnte ich sehen, dass wir die Möglichkeit hinzufügen, dass Leute Versionen auf PyPI als unsicher markieren und Leute warnen, wenn sie eine unsichere Version auf ihrem System installiert haben (oder zumindest, wenn sie eine installieren wollen).

Nun, da wir --upgrade , ist das andere zusammenhängende Thema hier, was wir mit pip install Vergleich zu pip install --upgrade tun sollen. Persönlich denke ich, dass wir beide dasselbe bedeuten sollten, _JEDOCH_ könnte es vernünftiger sein, die Diskussion zuerst nur auf das Verhalten von --upgrade und pip install vorerst in Ruhe zu lassen. Sobald wir die Lösung für das Upgrade gefunden haben, können wir angehen, was wir mit pip install selbst tun werden.

[1] Obwohl es ehrlich gesagt nicht eng mit Numpy zusammenhängt. Ich habe immer wieder Leute gesehen, die ihre Systeme oder ihre Installationen wegen einer unbeabsichtigten Ugprade kaputt gemacht haben. Es ist wahr, dass viele Projekte keine korrekten unteren Grenzen haben, aber ich glaube, es ist genauso wahr (oder mehr), dass sie auch keine korrekten oberen Grenzen haben. Eine besonders wichtige Sache ist, dass es möglich ist, die richtigen unteren Grenzen zum Zeitpunkt der Verpackung zu bestimmen, aber es ist unmöglich, die richtigen oberen Grenzen zu bestimmen.

[2] Optionen sind nicht kostenlos, sie verursachen Kosten und es ist wichtig zu versuchen, die Anzahl der Optionen so weit wie möglich zu reduzieren. Während man sie normalerweise nicht auf Null reduzieren kann, ist ein Muster, das ich bei OSS-Software viel zu oft sehe, der Wunsch, allen zu gefallen, indem immer mehr Optionen hinzugefügt werden, obwohl es in Wirklichkeit nur ein Mechanismus ist, um zu vermeiden, dass eine Entscheidung getroffen wird, die bei uns unpopulär sein könnte eine Gruppe von Menschen.

Danke für die Wortwand :). Ein paar Antworten und einige Gedanken.

tl;dr: Ich stimme dir bezüglich der Kosten von Optionen und mentalen Modellen rund um Pip und so weiter zu. Ich habe immer noch große Angst vor den Auswirkungen Ihres Vorschlags.

bzgl. Aktualisierung sicherer: Wir können ziemlich sicher sein, dass vorhandene Sicherheitsfehler irgendwann angreifbar sind, wenn man nie ein Upgrade durchführt. OTOH Wenn man immer ein Upgrade macht, werden zwar gelegentlich Sicherheitsfehler eingeführt, diese werden aber bei späteren Upgrades wieder entfernt.

Das Wichtigste ist in _jedem_ Fall, dass ein systemischer, automatisierter Upgrade-Prozess stattfindet, den wir heute nicht haben. Wenn dies nicht der Fall ist, glaube ich, dass ein standardmäßiges Upgrade deutlich besser ist.

bzgl. Obergrenzen und Untergrenzen: Es gibt absolut keine Möglichkeit, die Untergrenzen heute richtig zu bestimmen. Sie haben Recht, dass man im logischen Sinne nur die Untergrenze genau angeben kann, aber die Realität ist, dass sie heute niemand genau angibt: - Es reagiert vollständig auf Fehler von Leuten, bei denen sie feststellen, dass die Untergrenze nach dem Debuggen falsch ist . Und es gibt nicht einmal unter den Leuten, mit denen ich gesprochen habe, Konsens darüber, was getan werden sollte, wenn untere Grenzen mit optionalen Dingen interagieren - sollten die Leute Merkmale erkennen oder die untere Grenze erhöhen oder einfach abstürzen, wenn ein inkompatibler Weg eingeschlagen wird? Wenn pip das von mir vorgeschlagene select-oldest-version-Ding hätte, wäre dies nicht der Fall, und es wäre _viel_ vernünftiger anzunehmen, dass untere Grenzen vernünftig wären.

Aber ich habe _buchstäblich die Anzahl der kaputten Umgebungen verloren, die ich für Leute repariert habe, indem ich ihnen 'pip install -U-Paket' gesagt habe.

Ich verstehe das 'neige Problem' nicht wirklich? Ist das die Sammlung von Projekten, die über Abhängigkeiten lügen, um Upgrades zu vermeiden?

pip wird in 3 verschiedenen Kontexten verwendet IME:

  • Pflege von Produktionsumgebungen
  • reproduzierbare neue Umgebungen bauen - zB Container-Builds
  • testen

Für die beiden letzteren ist mir der Upgrade-Algorithmus egal, solange er deterministisch ist.
Das erste interessiert mich sehr, und es hört sich so an, als ob das, was wir hier haben, ein Projekt ist, das aufgrund einer Kombination von API- und ABI-Brüchen den größten Teil der Schmerzen verursacht - weil numpy tatsächlich eines davon hat?

WENN es eine Produktions-Wartungs-Sache gäbe, um Upgrades von allem durchzuführen, dann würde ich die vorgeschlagene Änderung, die installiert werden soll, nicht zurückdrängen. Aber das tut es nicht, und wir haben keine Ahnung, wie lange es dauern wird, bis es eines gibt - AIUI, der Befehl, der es möglicherweise getan hat, wurde tatsächlich verschoben, also sollten wir erwarten, _kein_ zu haben?

Ich verstehe das 'neige Problem' nicht wirklich? Ist das die Sammlung von Projekten, die über Abhängigkeiten lügen, um Upgrades zu vermeiden?

Jawohl. Bibliotheken wie scipy und scikit-learn lügen zu pip, dass sie nicht von numpy abhängen, damit pip nicht eine halbstündige Neuinstallation neuerer numpy über ein möglicherweise optimiertes oder sogar selbst kompiliertes numpy startet.

WENN es eine Produktions-Wartungs-Sache gäbe, um Upgrades von allem durchzuführen, dann würde ich die vorgeschlagene Änderung, die installiert werden soll, nicht zurückdrängen. Aber das tut es nicht, und wir haben keine Ahnung, wie lange es dauern wird, bis es eines gibt - AIUI, der Befehl, der es möglicherweise getan hat, wurde tatsächlich verschoben, also sollten wir damit rechnen, keinen zu haben?

Ich glaube nicht, dass irgendjemand dies zurückgedrängt hat, außer dass die Leute darauf warten, dass der Resolver zuerst fertig ist, weil man den Eindruck hat, dass Upgrade-All ohne einen Resolver eine erhöhte Tendenz haben wird, zu inkonsistenten Umgebungen zu führen. Ich weiß nicht, vielleicht sollten wir einfach weitermachen und einen upgrade-all Befehl implementieren, auch wenn wir wissen, dass es anfangs unvollkommen sein wird... das Perfekte ist der Feind des Guten und so. Vielleicht könnten wir versuchen, alles zu aktualisieren und dann automatisch den neuen pip check Code ausführen, um Leute zu warnen, wenn etwas kaputt geht, das sie möglicherweise reparieren müssen.

das 'Nepp-Problem'

Ja, das liegt zum Teil daran, dass Pakete wie numpy teuer in der Installation sind oder dazu neigen, einfach Fehler zu machen (denken Sie an: Windows-Benutzer ohne Compiler). Für numpy selbst ist dieses Problem jetzt stark reduziert, da wir eine bessere Wheel-Unterstützung haben, aber es gibt neben numpy viele Pakete, die einen Compiler benötigen. Es ist außerordentlich frustrierend, wenn Sie nur versuchen, ein triviales reines Python-Paket zu aktualisieren und dann plötzlich Unable to find vcvarsall.bat .

Und es liegt zum Teil daran, dass die Leute wählerische Vorlieben für Dinge wie numpy haben. Zum Beispiel ist es üblich, numpy-mit-proprietären-MKL-Patches zu mischen, die von Anaconda installiert wurden, während pip für andere Pakete verwendet wird, die Anaconda nicht liefert. Und dann könnte pip install -U other-package das Anaconda-Numpy wegwerfen und durch ein PyPI-Numpy ersetzen aus unter conda gelöscht.

Und es ist teilweise nur so, dass numpy ein kanonisches Beispiel für ein Paket ist, von dem _viele_ andere Pakete auf komplizierte Weise abhängen C oder D oder ... Rekursive Upgrades schaffen überraschende Kopplungen zwischen verschiedenen Paketen.

Es ist außerordentlich frustrierend, wenn Sie nur versuchen, einige zu aktualisieren
triviales pure-python-Paket und dann plötzlich vcvarsall.bat nicht zu finden
.

Genau dies. Sie können dies mit --no-deps , oder
--only-binary , aber es macht, was eine wirklich einfache Aktivität sein sollte
in etwas wirklich nerviges. Nach meiner Erfahrung die einzige Möglichkeit zu pflegen
Eine Umgebung besteht darin, die schwer zu installierenden Pakete sorgfältig einzurichten
manuell, pflegen Sie diese von Hand und lassen Sie sie dann nicht von pip aktualisieren
automatisch. Der letzte Teil ist mit dem Strom nicht ohne weiteres möglich
Verhalten von --upgrade .

Für ein nicht-numpy-Beispiel lässt sich lxml unter Windows nicht einfach erstellen.
liefert keine Räder und ist von vielen Dingen abhängig. Eine neue
Veröffentlichung von lxml (auf die ich wahrscheinlich nicht upgraden möchte,
da ich das Rad von Christoph Gohlke beim Bauen manuell herunterladen muss
und installieren Sie es von Hand) können Upgrades aller Art dazu führen, dass
Scheitern. Nicht eifrige Upgrades würden dieses Problem für mich beheben.

und dann lasse pip sie nicht automatisch aktualisieren.

Ich nehme an, die richtige Lösung dafür wäre das Anheften von Versionen, das https://github.com/pypa/pip/issues/654 verfolgt, und dann das Ausgeben einer Warnung, wenn eine angeheftete Version dazu führt, dass eine dep-Anforderung nicht erfüllt wird. Dadurch können Benutzer ein Paket _wirklich_ manuell verwalten.

Für eine Produktionsumgebung wahrscheinlich. Aber für eine Umgebung wie meinen Laptop oder eine virtuelle Entwicklungsumgebung, die ich zum Testen verwende, wird das Problem durch das Anheften von Versionen überspezifiziert (und erfordert, dass ich auf Versionsebene verwaltet werde). Was ich eigentlich will, ist genau das, was ich gesagt habe - "nicht upgraden, es sei denn, ich bitte Sie darum".

pip wird in 3 verschiedenen Kontexten verwendet IME:

  • Pflege von Produktionsumgebungen
  • reproduzierbare neue Umgebungen bauen - zB Container-Builds
  • testen

@rbtcollins Mir ist nicht klar, ob Ihre Definition von "Produktionsumgebung" alles umfasst, von "neuer Benutzer, der Python + einige Pakete installiert hat" über "fortgeschrittene Benutzer mit mehreren Venvs" bis hin zu "Produktionsbereitstellungen mit Apps/Websites"? Ihre Kommentare zur Sicherheit scheinen sich hauptsächlich um die letzte Kategorie zu sorgen, aber das ist imho die am wenigsten interessante, da sie sich an die sachkundigsten Benutzer richtet. Standardeinstellungen sollten für nicht erfahrene Benutzer ausgewählt werden, die Python auf ihrem Laptop/Desktop installiert haben und ihre Analyse oder Website zum Laufen bringen möchten.

Ich möchte dieses Thema und die damit verbundene(n) Diskussion(en?) wieder aufleben lassen.

@rbtcollins Wurden Ihre Bedenken angesprochen? Falls nicht, weisen Sie bitte auf offene Bedenken hin.

Es gab mindestens 2 Leute in der Distutils-Sig-Diskussion, die gegen die ganze Idee waren, pip install ein Upgrade durchzuführen. Ich bleibe bereit, den Konsens der Gemeinschaft zu akzeptieren, aber ich fühle mich mit der Idee auf einer rein persönlichen Ebene unwohl. Es fühlt sich für mich nicht so an, als ob wir einem Konsens nahe sind, dass ein bloßes pip install foo ein bereits installiertes foo aktualisieren sollte.

Ich bin mir nicht sicher, ob es hier einen Konsens gibt. Eher zwei Anwendungsfälle, die unterschiedliche Verhaltensweisen erfordern. Oder vielleicht drei:

  1. Automatisiertes Skript (oder Benutzer, der nicht manuell überprüfen möchte), der sicherstellen möchte, dass "foo verfügbar ist", aber keine unnötigen Änderungen am System vornehmen möchte. Idempotente Installation.
  2. Benutzer, der die neueste Version von foo möchte. Installieren oder aktualisieren.
  3. Automatisiertes Skript, das sicherstellen möchte, dass foo (sofern vorhanden) auf dem neuesten Stand ist. Upgrade ohne Installation.

All dies scheint gültige Anwendungsfälle zu sein. Alle können in Bezug auf die anderen mit ausreichenden manuellen Prüfungen oder zusätzlichem Scripting implementiert werden. Wir haben derzeit (1) und (2) über install und install -U (zumindest im einfachen Fall - rekursive Upgrades ignoriere ich bewusst vorerst).

Es gibt einige Leute, die argumentieren, dass das Standardverhalten von install dass Benutzer Fehler machen, weil sie Verhalten erwarten oder brauchen (2) und nicht verstehen, dass sie es bekommen (1). Vielleicht ist das so - meine Erfahrung ist zu begrenzt, um zu sagen, dass sie falsch sind. Unsere Standardeinstellungen können falsch sein.

Betrachtet man die praktischen Aspekte (der grundlegenden Frage "sollte das Upgrade standardmäßig installiert werden?"):

  1. Es besteht kein Konsens darüber, wie eine Bare-Installation eine bereits vorhandene Anforderung behandeln soll. Aber immer eine Option zu verlangen, ist eine schlechte Benutzeroberfläche, also müssen wir uns entscheiden.
  2. Wenn Sie nichts tun, wenn die Anforderung vorhanden ist, wird die Wahrscheinlichkeit einer unerwarteten Änderung am System des Benutzers minimiert. Beachten Sie, dass das Zurücksetzen einer solchen unerwarteten Änderung nicht trivial ist.
  3. Nichts zu tun, wenn die Anforderung vorhanden ist, ist das aktuelle Verhalten, so dass es den Vorteil hat, dass die Skripte der Benutzer oder die vorhandene Dokumentation nicht beschädigt werden.
  4. Die typische englische Verwendung von "install" beinhaltet nicht den Sinn von "upgrade". Wenn Sie etwas durch eine neuere Version ersetzen, würden Sie normalerweise sagen, dass Sie es "aufgerüstet" haben, nicht, dass Sie es "installiert" haben.

Die Argumente für einen Wechsel scheinen zu sein:

  • Es ermutigt die Leute zu glauben, dass sie auf dem neuesten Stand sind, während sie veraltete Software ausführen (schlecht aufgrund von Fehlern und möglicherweise Sicherheitslücken). Sicherlich ist das nur ein Fall, in dem die Leute nicht verstehen, was der Befehl tut, den sie ausführen?
  • Es verpasst eine Gelegenheit, die Leute auf dem Laufenden zu halten. Aber ist es die Rolle des Installationsbefehls, dies zu tun? Wäre ein Befehl "Alle meine Sachen aktualisieren" dafür nicht besser? Das Argument hier scheint zu sein, dass wir die Leute vor sich selbst schützen und Upgrades durchführen sollten, die sie nicht ausdrücklich angefordert haben.
  • Das aktuelle Verhalten bricht Systeme. Ohne konkrete Angaben ist es schwer, darauf zu antworten. Wenn pip install foo , um foo zu bekommen, das System eines Benutzers zerstört, ist das ein Fehler - und ein schlechter. Aber es scheint eher ein Fehler im Abhängigkeitsverwaltungscode zu sein, als weil pip install foo ein bereits installiertes foo nicht aktualisiert hat. Oder ein Dokumentationsfehler (verwirrend "wie man zum ersten Mal installiert" mit "wie man von einer früheren Version aktualisiert"), aber das ist nicht "kaputt", nur verwirrend.
  • Es entspricht dem Verhalten anderer Systeme. Die Debatte um distutils-sig scheint darauf hinzudeuten, dass dies bei weitem nicht so eindeutig ist, wie es zunächst klang.

IMO, wir _müssen_ eine Schlussfolgerung darüber ziehen, wie eine einfache Installation eines Pakets ohne Abhängigkeiten funktioniert, bevor wir anfangen, die komplexeren Fälle zu diskutieren. Das ist der überwiegende Anwendungsfall. Pakete mit Abhängigkeiten, Konfliktlösung, rekursive Upgrades sollten alle erst in Betracht gezogen werden, wenn wir eine solide und vereinbarte Grundlage dafür haben, wie eine einfache Paketinstallation funktioniert.

Persönliche Ansicht - an den traditionellen Optionen install und install --upgrade ist nichts auszusetzen. Sie erscheinen mir klar und natürlich (Wiederholung: in den einfachen Fällen). Es gibt keine Option "Upgrade, aber nur, wenn bereits vorhanden", aber der natürliche Ort dafür wäre ein neuer upgrade Befehl, und ich denke nicht, dass die Notwendigkeit hoch genug ist, um einen neuen Unterbefehl zu rechtfertigen, also ' m OK, diesen Fall manuell bearbeiten zu müssen.

Es ist falsch, das Verhalten von 'pip install' zu ändern. Es ist nichts falsch an install, was "sicherstellen, dass es installiert ist" bedeutet, und es ist nichts falsch an install, was bedeutet, dass das genannte Paket durch die neueste Version ersetzt wird, und die Entwickler sind schlau genug, sich davon zu überzeugen, dass jedes Verhalten intuitiver ist. Aber es ist falsch, Tausenden von Entwicklern die Nachmittage zu stehlen, die sich auf das aktuelle Verhalten verlassen und die beim nächsten Mal, wenn sie dumm genug sind, pip zu aktualisieren, plötzlich Umgebungen haben werden.

Der Vorschlag, die Installation der direkt benannten Abhängigkeit zu ändern, gefiel mir nicht, aber der Rest der vorgeschlagenen Änderungen in Bezug auf die Rekursivität von Paketaktualisierungen usw. gefiel mir.

Gerade heute hat mich jemand um Hilfe gebeten, weil er verwirrt war, warum pip install --pre docker-py 1.9.0rc2 nicht installiert hat, aber pip install docker-py==1.9.0rc2 . Sie hielten es für einen Fehler in pip, bis herausgefunden wurde, dass der Grund dafür war, dass sie bereits eine frühere Version von docker-py installiert hatten und diese verwendet wurde.

Dies entspricht meiner eigenen Verwendung, ich rufe pip nie ohne ein -U außer aus Faulheit, um diese zusätzlichen paar Zeichen einzugeben, und wenn ich es auslasse, bin ich die Hälfte der Zeit verärgert und muss am Ende erneut Führen Sie den Befehl mit einem -U dort aus.

@dholth sagt, es sei falsch, die Nachmittage von Tausenden von Entwicklern zu stehlen, die sich auf das aktuelle Verhalten verlassen, aber was ist mit den Nachmittagen von Tausenden von Entwicklern, die vom aktuellen Verhalten gebissen werden? Wie immer ist jeder Bruch immer eine Abwägung der Bruchkosten gegen den Nutzen. Es macht das Verhalten von pip standardmäßig weniger überraschend, Sie müssen die Umgebung nicht untersuchen, um herauszufinden, was das Ergebnis eines Befehls sein wird, Sie müssen nur den Befehl kennen.

Ich denke, was auch immer die gewählte Lösung ist, wir müssen eine Option bereitstellen, um das alte Verhalten zu aktivieren, um den Übergang zu glätten.
Wenn wir ein Upgrade von pip install foo , benötigen wir ein --no-upgrade .
Wenn wir das rekursive Verhalten des Upgrades entfernen, benötigen wir ein --recursive .

Ich stimme einem --no-upgrade Flag auf jeden Fall zu (und behalte das --upgrade Flag, damit es zum Upgrade zurückgedreht werden kann, wenn jemand es deaktiviert hat). Ich bin mir nicht sicher, ob die --recursive Flagge langfristig gilt, aber ich bin nicht fest dagegen.

Ich denke, ich würde durch diese Änderung einen großen Bruch erleben, aber hauptsächlich bei nicht interaktiven pip-Aufrufen, während 'pip install -U' normalerweise interaktiv passiert und vor allem dann, wenn jemand Entwicklungsarbeit durchführt und verfügbar ist, um sich mit den Problemen zu befassen Folgen. Aus diesem Grund habe ich scherzhaft vorgeschlagen, isatty() zu überprüfen, um zwischen dem einen oder dem anderen Verhalten zu wählen. Aber gibt es eine Möglichkeit, beide Zeiträume zu messen, oder ist es nur eine kreisförmige Flut von Meinungen? Meine Meinung ist, dass ich als erfahrene Person install mit -U erneut eingeben muss, aber es geht schnell, während das Reparieren einer virtualenv, wenn ich es am wenigsten erwartet habe, Hunderte Male langsamer ist.

Eine andere Lösung, die bereits diskutiert wurde, besteht darin, dem neuen Verhalten einen neuen Namen zu geben (einen Namen, den man sich leichter merken kann als pip install -U?) und die Leute über die neue Best Practice aufzuklären; wenn die n00bs, die theoretisch die meisten Schwierigkeiten haben, die neue Dokumentation lesen und den neuen Namen verwenden, ist das Problem gelöst.

Wo wir gerade beim Thema sind, wo ist der Befehl 'Pip Rollback'? Vor und nach jedem Aufruf sollte pip die Versionen und eventuell die Räder jedes installierten Pakets zusammen mit einem Zeitstempel in einem Protokoll speichern. Wenn es dann ein Problem gibt, können Sie einfach rückwärts gehen, ohne viel Aufhebens.

Ja, mir ist auch bewusst, dass einige aktuelle Best Practices, die mehr Arbeit bedeuten, auch einige dieser Probleme lösen könnten, aber die Best Practices einer Person sind nur die unnötige zusätzliche Arbeit einer anderen Person.

Die Tatsache, dass der Bruch hauptsächlich bei nicht-interaktiven Pip-Aufrufen auftreten wird, ist eigentlich ein guter Punkt, aber ich denke eher daran, dass wir es tun sollten. Der primäre Ort, an dem das aktuelle Verhalten Sinn macht, ist beim Skripten mit pip, und wenn Sie Skripte erstellen, ist das Hinzufügen eines zusätzlichen Flags zum Befehl keine große Belastung, aber wenn Sie pip interaktiv ausführen, sollte die Standardoption die Option sein, die du wirst höchstwahrscheinlich wollen.

Wenn Sie einen Rollback-Befehl wünschen, schlage ich ein anderes Problem vor.

Nur in Bezug auf das Bikeshedding der Benutzeroberfläche gefällt mir immer noch die Idee, dass das idempotente / skriptorientierte Verhalten ein neues Verb erhält, wie pip require numpy -- für mich macht das einen guten Job, den konzeptionellen Unterschied zu erfassen (während Pip's Dickicht von Flags ist sehr verwirrend und ihre Interaktion ist schwer vorherzusagen), und beim Skripting von IME ist es einfacher, sich daran zu erinnern, das Verb zu verwenden, das das bedeutet, was Sie wollen, als sich daran zu erinnern, jedes Mal ein zusätzliches Flag zu übergeben.

Aber ich denke, das Verb, das wir den Benutzern zuerst beibringen (das ist install ), sollte das Verb sein, dessen Voreinstellungen sich an neuen Benutzerbedürfnissen orientieren, dh interaktiver Gebrauch, wobei pip install django als pip install django==$LATEST interpretiert wird

Aber gibt es eine Möglichkeit, beide Zeiträume zu messen, oder ist es nur eine kreisförmige Flut von Meinungen?

Genau das ist mein Punkt. Ich glaube nicht, dass es für beide Seiten zwingende Argumente gibt (wie sie wahrscheinlich das andere Lager überzeugen werden). Und in diesem Fall gewinnt der Status Quo. Meine größte Sorge hier ist, dass wir (als Projekt) keine guten Mittel haben, um diese Art von Situation zu schlichten, und am Ende schwebt dies für immer über uns, weil es immer die Möglichkeit gibt, dass jemand eine PR begehen könnte, einfach weil diejenigen, die beim letzten Mal Einspruch erhoben haben, nicht bemerkt haben, dass eine Diskussion wieder aufgenommen wird. Was wir brauchen, ist eine Art Äquivalent zu den abgelehnten PEPs von Python, die es uns ermöglichen würden, zu sagen "wir haben (aus den folgenden Gründen) beschlossen, nichts zu tun" und dann in der Lage zu sein, den Prozess von jemandem abzukürzen, der darum bittet, die Entscheidung zu überdenken und all die alten fruchtlosen Argumente noch einmal durchgehen zu müssen.

Ich würde lieber einen Weg finden, das aktuelle Nicht-Standard-Verhalten für Leute, die es brauchen, leichter zugänglich zu machen, als Zeit mit Argumenten zu verschwenden, die einfach dazu führen, dass sich beide Seiten immer mehr in ihren Positionen verankern. Obwohl ich nicht wirklich weiß, wie das geht - ich verstehe wirklich nicht, was so verwirrend ist an " install installiert, install --upgrade installiert, aber auch aktualisiert, wenn nötig".

Aber ich denke, das Verb, das wir den Benutzern zuerst beibringen (das ist install), sollte das Verb sein, dessen Standardeinstellungen auf neue Benutzerbedürfnisse ausgerichtet sind, dh interaktive Verwendung, interpretieren pip install django als Bedeutung von pip install django==$LATEST usw.

Nun, obwohl ich Ihren Standpunkt sehe, dass wir die interaktive Nutzung (durch neue Benutzer) als den Hauptanwendungsfall betrachten sollten, bin ich nicht überzeugt, dass dies "Installation oder Upgrade" impliziert. Ich würde argumentieren, dass der Fehlermodus eines impliziten Upgrades (Sie aktualisieren eine vorhandene Installation ohne Absicht und unterbrechen dabei einen anderen Teil Ihres Systems) ausreichend schlecht (selbst für einen erfahrenen Benutzer), dass es eine Markierung rechtfertigt "Ich verstehe die Konsequenzen".

Die Projektanweisungen "Verwenden Sie pip install FOO und Sie können loslegen" können (und sollten) geändert werden. Wir sollten eine Entscheidung wie diese nicht auf der Grundlage der fehlerhaften Dokumentation anderer Leute fällen, egal wie viel davon vorhanden ist. Der Wortlaut sollte einfach lauten: "Wenn Sie FOO noch nicht haben, verwenden Sie pip install FOO und Sie können loslegen. Wenn Sie FOO bereits haben, aber die neue Version möchten, verwenden Sie pip install --upgrade FOO ".

Ich weiß, dass es anekdotische Beweise dafür gibt, dass Leute viel Zeit damit verbringen, herauszufinden, was schief gelaufen ist, weil sie --upgrade . Aber wie sollen wir das beurteilen, da es (per Definition) unmöglich ist, Beweise dafür zu erhalten, wie viele Menschen _keine_ Probleme mit dem aktuellen Verhalten hatten? Nehmen Sie eine Änderung vor und warten Sie auf Fehlerberichte von Leuten, die sagen: "Ich habe pip install foo und es hat mein bestehendes Foo aktualisiert, was die Latte gebrochen hat - wie kann ich dieses Chaos aufheben?" Ich persönlich möchte Menschen in dieser Situation nicht unterstützen müssen...

Mercurial-Maßnahmen, indem sie Nutzungsstatistiken von Facebook abrufen, haben sie ein spezielles Unternehmens-Plugin, um sie aufzuzeichnen.

Ich verstehe wirklich nicht, was an "Installationen installieren, installieren --upgrade installiert, aber auch Upgrades bei Bedarf" so verwirrend ist.

Es ist nicht wirklich verwirrend, aber das Standardverhalten erfordert, dass Sie wissen, was bereits auf Ihrem System installiert ist, um herauszufinden, was das Ergebnis des Befehls sein wird. Besonders bei virtuellen Umgebungen ist es leicht, nicht zu erkennen, was genau Sie installiert haben, und davon auszugehen, dass etwas nicht installiert ist (und dann verwirrt zu werden, wenn Sie nicht die erwartete Version erhalten).

Ich habe zu jeder Zeit ungefähr 50-100 verschiedene virtuelle Umgebungen auf meinem PC, eine für jedes Projekt, an dem ich arbeite. Es ist im Grunde unmöglich für mich zu wissen, was in einer bestimmten Umgebung installiert ist, ohne dort zu sitzen und pip list und dann die gesamte Liste durchzugehen, was viel mehr Zeit in Anspruch nimmt, als ich jemals tun werde.

Wir sollten eine Entscheidung wie diese nicht auf der Grundlage der fehlerhaften Dokumentation anderer Leute fällen, egal wie viel davon vorhanden ist.

Ich glaube nicht, dass das ganz richtig ist. Keine der beiden Optionen ist objektiv richtig, so dass wir uns dem Versuch überlassen, eine subjektive Antwort darauf zu finden, was besser ist, und zu sehen, welche Fehler andere Leute in ihrer Dokumentation gemacht haben, ist keine schlechte Informationsquelle. Um ein extremes Beispiel zu verwenden, wenn buchstäblich jeder es falsch macht, dann würde das darauf hindeuten, dass der falsche Weg zu offensichtlich und der richtige Weg nicht offensichtlich genug ist.

Aber wie sollen wir das beurteilen, wenn man bedenkt, dass es (per Definition) unmöglich ist, nachzuweisen, wie viele Menschen keine Probleme mit dem aktuellen Verhalten hatten?

Metriken in OSS sind ein Problem :( Irgendwann wäre es großartig, wenn wir einige bekommen könnten, damit wir Dinge wie "Diese Person hat die Installation ausgeführt und dann nichts anderes" im Vergleich zu "Diese Person hat die Installation ausgeführt, dann fast sofort wieder lief es mit --upgrade ". Leider ist das noch in der "Gee it's nice"-Phase und noch lange nicht fertig, also müssen wir Hühnerknochen werfen und versuchen, die Realität aus der Vorstellung zu erraten.

das Standardverhalten erfordert, dass Sie wissen, was bereits auf Ihrem System installiert ist

Obwohl ich weiß, dass dies ein Problem sein könnte, bin ich nicht wirklich überzeugt, dass es ein so großes Problem ist. Immerhin, wenn Sie pip install tun und das Paket bereits vorhanden ist, erhalten Sie sofort Feedback:

(x) C:\Work\Scratch>pip install wheel
Requirement already satisfied (use --upgrade to upgrade): wheel in c:\work\scratch\x\lib\site-packages

Es ist also nicht so, dass Sie ewig brauchen werden, um herauszufinden, dass Sie ein Upgrade benötigen oder wie dies geht.

Ich hätte lieber einen sicheren Standard, bei dem das System erkennen kann, dass Sie möglicherweise die Alternative gemeint haben (plus eine klare Nachricht, die Ihnen sagt, was zu tun ist) über einen Standard mit dem Potenzial, nicht verwandte Dinge zu beschädigen, und keinen Wiederherstellungsmechanismus.

Je öfter wir diese Diskussion führen, desto weniger verstehe ich den Vorteil eines Upgrades als Standard.

Immerhin, wenn Sie pip install tun und das Paket bereits vorhanden ist, erhalten Sie sofort Feedback.

Irgendwie, obwohl es leicht ist, in der ganzen anderen Ausgabe unterzugehen, selbst wenn eine moderate Anzahl von Paketen installiert wird:

$ pip install Pyramid
Collecting Pyramid
  Using cached pyramid-1.7-py2.py3-none-any.whl
Collecting WebOb>=1.3.1 (from Pyramid)
  Using cached WebOb-1.6.1-py2.py3-none-any.whl
Collecting translationstring>=0.4 (from Pyramid)
  Using cached translationstring-1.3-py2.py3-none-any.whl
Collecting zope.deprecation>=3.5.0 (from Pyramid)
Collecting venusian>=1.0a3 (from Pyramid)
Requirement already satisfied (use --upgrade to upgrade): setuptools in ./lib/python3.5/site-packages (from Pyramid)
Collecting PasteDeploy>=1.5.0 (from Pyramid)
  Using cached PasteDeploy-1.5.2-py2.py3-none-any.whl
Collecting repoze.lru>=0.4 (from Pyramid)
Requirement already satisfied (use --upgrade to upgrade): zope.interface>=3.8.0 in ./lib/python3.5/site-packages (from Pyramid)
Installing collected packages: WebOb, translationstring, zope.deprecation, venusian, PasteDeploy, repoze.lru, Pyramid
Successfully installed PasteDeploy-1.5.2 Pyramid-1.7 WebOb-1.6.1 repoze.lru-0.6 translationstring-1.3 venusian-1.0 zope.deprecation-4.1.2

Ich hätte lieber einen sicheren Standard, bei dem das System erkennen kann, dass Sie möglicherweise die Alternative gemeint haben (plus eine klare Nachricht, die Ihnen sagt, was zu tun ist) über einen Standard mit dem Potenzial, nicht verwandte Dinge zu beschädigen, und keinen Wiederherstellungsmechanismus.

Sehen Sie, ich glaube nicht, dass ein standardmäßiges Upgrade überhaupt unsicher ist (wenn Sie die andere Änderung zum Upgrade berücksichtigen). Ich finde mehr Software, die nicht mit einer älteren Version von etwas funktioniert, mit der ich installiert habe, als Software, die mit einer neueren Version nicht funktioniert. Ich weiß bereits, welche Versionen möglicherweise installiert werden, weil ich sie explizit in der Befehlszeile benannt habe, sodass wir keine Dinge aktualisieren, die ich nicht explizit aufgerufen habe.

Irgendwie, obwohl es leicht ist, in der ganzen anderen Ausgabe unterzugehen, selbst wenn eine moderate Anzahl von Paketen installiert wird:

Guter Punkt, vielleicht sollte er hervorgehoben werden (wir verwenden Farben für Dinge wie Warnungen, dies scheint ein guter Kandidat zu sein).

Sehen Sie, ich glaube nicht, dass ein standardmäßiges Upgrade überhaupt unsicher ist

Angenommen, Sie haben foo 1.0 installiert und Bar 1.0, die von foo abhängt. Angenommen, bar funktioniert mit foo 1.0, aber nicht mit foo 2.0 (aber die Abhängigkeit ist nur von "foo", nicht "foo < 2.0", weil foo 2.0 noch nicht draußen war, als bar 1.0 veröffentlicht wurde, und woher sollte der Autor das wissen?) wenn ich pip install --upgrade foo tue, bricht der Takt. Und ich werde vielleicht lange nicht einmal feststellen, dass der Balken kaputt ist, wenn ich ihn nicht viel benutze. Das ist kein Fehlermodus, mit dem ich als Standardverhalten umgehen möchte - auch wenn es selten vorkommt und auch wenn es wohl an der Schuld liegt, in seinen Abhängigkeiten nicht strenger zu sein.

Ich möchte dies nicht zu einer Übung in "Mein Fehlerszenario ist schlimmer als Ihres" machen, da dies eine Debatte viel zu hitzig macht (siehe eine typische Sicherheitsdiskussion), aber ich denke, dass "überhaupt nicht unsicher" ist. falsch ist - bestenfalls ist es "unwahrscheinlich, dass ein Problem verursacht wird".

Natürlich erwähnen Sie hier "die andere Änderung zum Upgrade". Es gibt viel zu viele Kombinationen von Dingen, die vorgeschlagen werden und zu Abhängigkeiten werden (Upgrade, Upgrade alle, Rollback, rekursives Upgrade, nicht eifrige Upgrades, ...). Vielleicht sollten wir die Dinge einen Schritt nach dem anderen machen - warum lassen Sie diese Diskussion nicht vorerst und konzentrieren sich darauf, ein "sicheres Upgrade" einzurichten. Sobald wir pip install --upgrade an einem Ort haben, an dem wir garantieren können, dass es niemals das System von jemandem kaputt macht, können wir die Debatte über das Standardverhalten dann vielleicht wieder aufnehmen?

Ich möchte dies nicht zu einer Übung in "Mein Scheiternszenario ist schlimmer als Ihres" machen.

Genau! Lass uns nicht.

Es gibt viel zu viele Kombinationen von Dingen, die vorgeschlagen werden und zu Abhängigkeiten werden (Upgrade, Upgrade alle, Rollback, rekursives Upgrade, nicht eifrige Upgrades, ...). Vielleicht sollten wir die Dinge einen Schritt nach dem anderen machen - warum lassen Sie diese Diskussion nicht vorerst und konzentrieren sich darauf, ein "sicheres Upgrade" einzurichten.

Die "andere Änderung" ist der Wechsel zu nicht eifrigen Upgrades. Ich denke, dieses Thema befasst sich nur mit Verhaltensänderungen von install und install --upgrade und sollte daher eine Diskussion über Upgrade-Strategien beinhalten. Alles andere (Upgrade-All, Rollback) haben wir beim Öffnen dieses Themas explizit entkoppelt.

Sobald wir pip install --upgrade an einem Ort haben, an dem wir garantieren können, dass es niemals das System von jemandem kaputt macht, können wir die Debatte über das Standardverhalten dann vielleicht erneut eröffnen?

Dies würde bedeuten, zuerst #988 aufzulösen, das für eine ziemlich lange Zeit feststeckt.


Ich habe das Gefühl, dass wir zu lange Fahrradabfälle gemacht und darüber spekuliert haben, was der Benutzer tun würde. Ich denke, es ist nicht mehr sinnvoll, dies ohne einige Metriken zu tun, die schwer zuverlässig zu erhalten sind. Ich sah diese Änderung als schnelle Lösung an, die einen guten Mittelweg bot, bis #988 landete. Es war definitiv nicht schnell und es war fraglich, ob es ein guter Mittelweg ist. Ich denke, es könnte sich lohnen, einen Schritt zurückzutreten.


Es ist bereits möglich, nicht eifrige Upgrades durchzuführen, wenn Sie möchten, aber um das herauszufinden, ist eine Google-Suche erforderlich, die schwieriger ist, als es sein sollte. Selbst wenn pip eine Option bei der Installation bietet, um nicht eifrige Upgrades durchzuführen, ist es besser als der Status Quo.

Außerdem glaube ich nicht, dass irgendjemand möchte, dass die aktuelle Standardeinstellung für "eifrige Upgrades" die Standardeinstellung ist. Wenn das nicht der Fall ist, muss ich es übersehen haben. Warum also nicht standardmäßig zu nicht eifrigen Upgrades wechseln? Solange wir die Standard-Upgrade-Strategie auf "Nicht-Eifrig" umstellen und _vielleicht_ eine Möglichkeit bieten, eifrige Upgrades durchzuführen, sind wir besser dran als der Status Quo.

Unter der Annahme, dass niemand gegen diese beiden Punkte ist, wäre eine minimale Störungsänderung:

  • pip install --upgrade bietet standardmäßig nicht eifrige Upgrades.
  • Fügen Sie ein --upgrade-strategy=[eager/non-eager] (mit beliebiger Schreibweise) hinzu, um Ihre Upgrade-Strategie auszuwählen, wenn Sie wirklich eifrige Upgrades anbieten möchten.

Wie klingt das?

Zusätzlich zu dem, was ich gerade kommentiert habe, ist dies meiner Meinung nach der Weg des geringsten Widerstands, um das nicht-rekursive Standardverhalten zu erreichen, das ich gerne durchstehen würde.

Ich bin der Meinung, dass die standardmäßige Installation eines Upgrades im Wesentlichen eine separate Diskussion ist. Es lohnt sich, darüber zu diskutieren, aber ich denke, dass es die Änderung der Upgrade-Strategie nicht aufhalten sollte.

(Ich habe das Gefühl, dass dies ein neues Thema für die Diskussion über das, was ich gerade vorgeschlagen habe, bedeuten würde, aber ich werde die ersten Meinungen hier aufnehmen, bevor ich das tue)

Nur zur Klarstellung - ich glaube nicht, dass nicht eifrige Upgrades das Problem beheben, dass "pip install --upgrade foo" foo von 1.0 auf 2.0 aktualisieren könnte, aber eine bereits installierte Leiste könnte eine Abhängigkeit von foo deklarieren (ohne Version) ) aber nicht mit 2.0 arbeiten? Ich kann nicht sehen, dass dies möglich ist (oder tatsächlich sollte) und dennoch ist das das Szenario, das mich daran stört, das Upgrade zum Standard zu machen.

Was nicht bedeuten soll, dass ich ein Problem mit Ihrem Vorschlag habe, als ersten Schritt nicht eifrige Upgrades einzurichten (ich bin trotzdem +1).

Ich würde argumentieren, dass der Fehlermodus eines impliziten Upgrades (Sie aktualisieren eine vorhandene Installation ohne Absicht und unterbrechen dabei einen anderen Teil Ihres Systems) ausreichend schlecht (selbst für einen erfahrenen Benutzer), dass es eine Markierung rechtfertigt "Ich verstehe die Konsequenzen".

Dies ist buchstäblich der Fehlermodus jeder einzelnen Sache, die Pip tut. Es ist auch der Fehlermodus, pip nicht auszuführen (zB die Veröffentlichung eines Sicherheits-Exploits, der auf Ihren aktuellen Stack abzielt, führt dazu, dass er nicht mehr funktioniert -> kaputt, ohne dass Sie Ihre Umgebung ändern). Personen, die pip betreiben, fordern ausdrücklich, dass alle von ihnen festgelegten Änderungen an ihrer Umgebung vorgenommen werden, mit allen damit verbundenen Risiken und Vorteilen.

Niemand führt pip install foo wenn er bereits _wissen_, dass foo installiert ist, denn das wäre albern. Benutzer müssen also bereits darauf vorbereitet sein, ihre Umgebung zu zerstören, denn das Installieren neuer Pakete (und das Einziehen ihrer willkürlichen transitiven Abhängigkeiten) ist genauso gefährlich wie das Upgraden vorhandener Pakete. Tatsächlich sind das Upgrade von foo und die Installation von foo _genau_ gefährlich, weil sie _genau dasselbe tun_ -- sie ziehen exakt die gleichen Versionen der exakt gleichen Pakete ein.

Das Argument, dass ein einfaches pip install numpy als pip install numpy==$LATEST interpretiert werden sollte, ist, dass dies viel einfacher und vorhersehbarer ist als das aktuelle (wobei pip install numpy als pip install numpy==$CURRENTLY_INSTALLED_VERSION interpretiert wird). es sei denn, es gibt derzeit keine installierte Version, in diesem Fall wird es als pip install numpy==$LATEST interpretiert - schauen Sie nur, wie lange das Schreiben dauert). Es reduziert den Zustandsraum, den der Benutzer im Auge behalten muss -- ich kann nicht sehen, wie die Reduzierung der möglichen Ergebnisse eines Befehls auf eine strikte Teilmenge dessen, was sie früher waren, es _mehr_ gefährlicher macht :-).

Es hat auch den wichtigen Vorteil, dass die Verbreitung von Pfaden durch die Pip-Interna tatsächlich _reduziert_ -- separate Optionen für jede Kleinigkeit zu haben, egal wie nützlich (voll/weniger), hat sehr erhebliche Kosten für die Betreuer und so wurde Pip die im Thema #pypa-dev beschriebene "Rube-Goldberg-Maschine der Traurigkeit".

Die Projektanweisungen "use pip install FOO and you're ready to go" können (und sollten) geändert werden.

Ich finde es schwer zu glauben, dass Sie sich dieses Argument gefallen lassen würden, wenn wir über eine Bibliotheks-API sprechen würden :-(. "Ja, viele Benutzer dieser API-Funktion rufen sie mit den Standardwerten auf, und ja, die funktionieren zu 95% von die Zeit, damit die meisten Benutzer nicht bemerken, dass ihr Code in den anderen 5 % der Fälle defekt ist.Die Lösung besteht darin, diese API so zu belassen, wie sie ist, und Fehlerberichte zu erstellen, in denen alle aufgefordert werden, die unbreakme=True hinzuzufügen kwarg auf jeden Anruf. Denn das ist völlig die Schuld des Benutzers."

Am Ende schwebt das für immer über uns, weil es immer die Möglichkeit gibt, dass jemand eine PR begehen könnte, einfach weil diejenigen, die beim letzten Mal Einspruch erhoben haben, nicht bemerkt haben, dass eine Diskussion wieder aufgenommen wird.

So funktioniert es jedoch nicht -- beachten Sie, dass diese Änderung auf Github ausführlich diskutiert wurde und dann eine Mailingliste im Heads-up erstellt wurde, um sicherzustellen, dass niemand überrascht war.

Ich wünschte eigentlich, es würde so funktionieren, denn diese Änderung wäre _fait accompli_ und wir könnten alle weitermachen und keine Zeit mehr damit verschwenden ;-). Und Spaß beiseite, es könnte für das Projekt tatsächlich gesünder sein, wenn sich jemand wie dstufft dazu entschließt, BDFL in Situationen wie der richtigen zu spielen. Im Moment ist das De-facto-Ergebnis, dass Veränderungen einfach unmöglich sind und ich langsam das Gefühl habe, dass es produktiver wäre, den Versuch aufzugeben, Pip zu verbessern, und stattdessen meine Energie zu verwenden / anderen zu empfehlen, ihre Energie in die Suche zu investieren Mache eine brauchbare Pip-Gabel :-(

Nur zur Klarstellung - ich glaube nicht, dass nicht eifrige Upgrades das Problem beheben, dass "pip install --upgrade foo" foo von 1.0 auf 2.0 aktualisieren könnte, aber eine bereits installierte Leiste könnte eine Abhängigkeit von foo deklarieren (ohne Version) ) aber nicht mit 2.0 arbeiten?

FWIW, ich glaube nicht, dass es funktioniert, auch wenn bar explizit von foo==1.0 abhängt.

/tmp/pip-testing
$ ls ./repo
bar-1.0.tar.gz  foo-1.0.tar.gz  foo-2.0.tar.gz

/tmp/pip-testing
$ pip install --find-links ./

/tmp/pip-testing
$ pip install --find-links ./repo bar
Collecting bar
Collecting foo==1.0 (from bar)
Building wheels for collected packages: bar, foo
  Running setup.py bdist_wheel for bar ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/20/cd/44/f59790040978a7eb9989ce680e85681c252516bd7fc9baf059
  Running setup.py bdist_wheel for foo ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/27/9a/5f/3e8efff98718d38adb7cf6b20e4435694e8c465085792441be
Successfully built bar foo
Installing collected packages: foo, bar
Successfully installed bar-1.0 foo-1.0

/tmp/pip-testing
$ pip install --upgrade foo
Requirement already up-to-date: foo in /home/pradyunsg/.venvwrap/venvs/tmp-734de48113851ca/lib/python3.5/site-packages

/tmp/pip-testing
$ pip install --find-links ./repo --upgrade foo
Collecting foo
Building wheels for collected packages: foo
  Running setup.py bdist_wheel for foo ... done
  Stored in directory: /home/pradyunsg/.cache/pip/wheels/9d/3e/ce/b183a52b3e6844394d6cbf5606acadf8c340d48ccfcf02cc1c
Successfully built foo
Installing collected packages: foo
  Found existing installation: foo 1.0
    Uninstalling foo-1.0:
      Successfully uninstalled foo-1.0
Successfully installed foo-2.0

/tmp/pip-testing
$ pip list
bar (1.0)
foo (2.0)
pip (8.1.2)
setuptools (25.0.0)
wheel (0.29.0)

/tmp/pip-testing
$ pip --version
pip 8.1.2 from /home/pradyunsg/.venvwrap/venvs/tmp-734de48113851ca/lib/python3.5/site-packages (python 3.5)

Ich glaube nicht, dass es funktioniert, auch wenn bar explizit von foo==1.0 abhängt.

Richtig, das ist der "Pip braucht einen echten Resolver"-Bug, der irgendwann behoben wird, aber eine große Aufgabe ist, also wollen wir nicht, dass er andere Dinge blockiert, wenn sie überhaupt vermeidbar sind.

OTOH Der Fall, in dem bar eine unversionierte Abhängigkeit von foo verwendet, ist im Grunde unmöglich richtig zu machen AFAICT, daher bin ich mir nicht sicher, was das mit irgendetwas zu tun hat. Die einzige Lösung dafür ist "nie wieder dein Venv anfassen", und selbst das ist nicht garantiert (aufgrund von Dingen wie neuen Sicherheitslücken oder Änderungen in externen APIs, mit denen du sprechen musst).

Tatsächlich sind das Upgrade von foo und die Installation von foo genauso gefährlich, weil sie genau dasselbe tun – sie ziehen genau dieselben Versionen derselben Pakete ein.

OK. Wir werden wirklich einfach _müssen_ zustimmen, in dieser Hinsicht anderer Meinung zu sein. Meiner Ansicht nach geht es um die Wahrnehmung des Benutzers - "foo installieren" bedeutet _etwas, was zuvor nicht vorhanden war_ zu Ihrem System hinzuzufügen, während "foo aktualisieren" _etwas ändert, das bereits vorhanden ist_. Für den Benutzer sind diese bei weitem nicht dasselbe.

Im Moment ist das De-facto-Ergebnis, dass Veränderungen einfach unmöglich sind

OK ich gebe auf. Ich glaube nicht, dass es einen Konsens über diese Änderung gibt, und ich halte es für falsch, sie ohne Konsens umzusetzen. Sie wissen, dass ich selbst nicht damit einverstanden bin, aber darum geht es hier nicht. Änderungen sind wirklich nicht unmöglich (wir haben viele Änderungen vorgenommen, einige ziemlich kontrovers), aber keine Seite in diesem Argument scheint die andere zu überzeugen. Aus meiner Sicht führt dies in der Regel dazu, dass der Status quo gewinnt - aber ich bin mir bewusst, dass ich, wenn ich sage, dass ich so wahrgenommen werde, dass "alles, was ich tun muss, um meinen Willen durchzusetzen, die Dinge aufhalten muss". IMO, es sagt etwas darüber aus, wo wir gerade stehen, dass ich so empfinde :-(

Ich verabschiede mich jetzt aus dieser Diskussion. Wenn jemand ein Argument vorbringt, das meine Meinung ändert, werde ich das anerkennen, aber ansonsten habe ich nichts mehr zu sagen. Wenn ich der letzte Verweigerer bin, der diese Änderung nicht vornimmt, erlaube ich allen, mich zu ignorieren - ich bin sicherlich nicht der Meinung, dass ich (oder irgendjemand) ein Veto gegen Änderungen haben sollte, und ich akzeptiere eine Mehrheitsbeschluss. Wenn andere immer noch Vorbehalte gegen diese Änderung haben, müssen sie ihre eigenen Argumente vorbringen (aber ich möchte die Teilnehmer daran erinnern, dass nicht jeder Github-Probleme liest - obwohl die Diskussion aus der Bahn gelaufen ist, gab es einige Kommentare zu Distutils- sig, dass IMO eine Antwort verdient).

Und Spaß beiseite, es könnte für das Projekt tatsächlich gesünder sein, wenn sich jemand wie dstufft dazu entschließt, BDFL in Situationen wie der richtigen zu spielen. Im Moment ist das De-facto-Ergebnis, dass Veränderungen einfach unmöglich sind

Obwohl ich nicht denke, dass unser derzeitiger Prozess optimal ist, denke ich, dass es nicht ganz so schlimm ist wie "Änderungen sind unmöglich". Im Allgemeinen würden wir früher so etwas wie pypa-dev ML mit einer einfachen Mehrheitsentscheidung unter Pip Core zur Sprache bringen, wenn es keinen klaren Konsens gab. Ich denke, es gibt jetzt drei aktive Pip-Core-Entwickler (Myself, @pfmoore und @xavfernandez). Könnten wir ein formalisierteres Verfahren verwenden? Ja möglicherweise. Könnte das eine BDFL-Rolle sein? Möglich, aber ich glaube auch nicht, dass das nötig ist.

Leider bedeutet der aktuelle Ad-hoc-Prozess normalerweise, dass einer der wichtigsten Mitwirkenden sich hinsetzen und beschließen muss, auf die Änderung zu drängen und zu sagen: "Ok, lasst uns darüber abstimmen" und einige Ad-hoc-Regeln dafür festlegen.

Erinnern Sie sich, es wurde vereinbart, das Verhalten von --upgrade zu ändern, was die Hauptsache ist, die Dinge wie Projekte, die von Numpy abhängen, daran hindert, ihre Abhängigkeit zu deklarieren. Diese spezielle Änderung ist nur eine Idee, die daraus entstanden ist und mehr eine UX-Sache als alles andere ist. Wie bei jedem Projekt, es sei denn, Sie sind der BDFL, wird es Zeiten geben, in denen der Entscheidungsprozess gegen die gewünschte Option verstößt. Ich habe nichts davon getan, weil ich mich in letzter Zeit auf Warehouse konzentriert habe, pip wird nach der Veröffentlichung wieder in mein Fadenkreuz kommen :)

Niemand führt pip install foo aus, wenn er bereits weiß, dass foo installiert ist, denn das wäre albern.

Ich vermute, Sie haben Recht, aber ich würde auch sagen, dass viele Leute pip install -r requirements.txt mit requirements.txt mit foo (was pip install foo ), obwohl sie wissen, dass foo täglich installiert wird.
Und sie sind zufrieden damit, dass pip es schnell macht, ohne zu prüfen, ob es etwas zu aktualisieren gibt.

Ich bin nicht gegen die Idee, dass pip install foo mit pip install foo==$LATEST äquivalent sein könnte (tatsächlich mag ich es), aber ich bin dagegen, dieses grundlegende Verhalten ohne eine Verfallsfrist (und eine Escape-Option zu) zu ändern das alte Verhalten beibehalten).
Ich bin mir nicht sicher, ob wir diese Lösung bereits besprochen haben, aber dies könnte eine neue Option für pip install --strategy für pip install :

  • no-upgrade wäre der Standard in Pip 9 und pip install --strategy=no-upgrade wäre das aktuelle pip install Verhalten
  • eager wäre das aktuelle pip install --upgrade Verhalten (und --upgrade ein veralteter Alias ​​für --strategy=eager )
  • non-eager wäre die Standardeinstellung in Pip 10
  • wir könnten uns oldest-compatible für #3188 vorstellen usw.

Beachten Sie, dass Sie auch strategy=non-eager in Ihre pip.conf einfügen können, um es direkt als Standard in pip 9 zu verwenden.

Könnten wir ein formalisierteres Verfahren verwenden? Ja möglicherweise.

:+1:

Und sie sind zufrieden damit, dass pip es schnell macht, ohne zu prüfen, ob es etwas zu aktualisieren gibt.

Es wäre wahrscheinlich immer noch ziemlich schnell TBH. Wir liefern Antworten in weniger als einer Millisekunde aus dem Fastly-Cache :)

Ich bin nicht gegen die Idee, dass pip install foo äquivalent zu pip install foo==$LATEST sein könnte (tatsächlich mag ich es), aber ich bin dagegen, dieses grundlegende Verhalten ohne eine Verfallsfrist zu ändern (und eine Escape-Option, um die altes Verhalten).

Ich komme mit einer Kündigungsfrist gut zurecht. Ich bin mir nicht sicher, ob es eine langfristige Option gibt, das alte Verhalten beizubehalten. Ich bin nicht dagegen, ich möchte nur sicherstellen, dass wir dies wirklich langfristig unterstützen sollten, Optionen im Allgemeinen sind mit Kosten verbunden und möchten sicherstellen, dass sich die Kosten lohnen.

Wie klingt das?

Gefolgt mit #3972.

Geschlossen, da #3972 fusioniert wurde.

Wir haben einen anderen Weg eingeschlagen, um das Verhalten von --upgrade .

Dieser Thread wurde automatisch gesperrt, da nach dem Schließen in letzter Zeit keine Aktivität stattgefunden hat. Bitte öffnen Sie eine neue Ausgabe für verwandte Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen