Pip: `pip install -U` aktualisiert bereits erfüllte Abhängigkeiten

Erstellt am 9. Juni 2011  ·  23Kommentare  ·  Quelle: pypa/pip

Wenn ich pip install -U foo , würde ich erwarten, dass die neueste Version von foo installiert wird und die Abhängigkeiten von foo nur neu installiert werden, wenn sie nicht bereits erfüllt sind. Tatsächlich werden jedoch alle Abhängigkeiten neu installiert, selbst wenn bereits identische Versionen installiert sind:


$ pip install -U django-supervisor
Downloading/unpacking django-supervisor
  Downloading django-supervisor-0.2.0.tar.gz
  Running setup.py egg_info for package django-supervisor
Downloading/unpacking supervisor (from django-supervisor)
  Downloading supervisor-3.0a10.tar.gz (438Kb): 438Kb downloaded
  Running setup.py egg_info for package supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
Downloading/unpacking meld3>=0.6.5 (from supervisor->django-supervisor)
  Downloading meld3-0.6.7.tar.gz
  Running setup.py egg_info for package meld3
Installing collected packages: django-supervisor, supervisor, meld3
  Found existing installation: django-supervisor 0.1.1
    Uninstalling django-supervisor:
      Successfully uninstalled django-supervisor
  Running setup.py install for django-supervisor
  Found existing installation: supervisor 3.0a10
    Uninstalling supervisor:
      Successfully uninstalled supervisor
  Running setup.py install for supervisor
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'docs/.build'
    Skipping installation of /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor/__init__.py (namespace package)
    Installing /usr/local/ejucovy/django/lib/python2.6/site-packages/supervisor-3.0a10-py2.6-nspkg.pth
    Installing echo_supervisord_conf script to /usr/local/ejucovy/django/bin
    Installing pidproxy script to /usr/local/ejucovy/django/bin
    Installing supervisorctl script to /usr/local/ejucovy/django/bin
    Installing supervisord script to /usr/local/ejucovy/django/bin
  Found existing installation: meld3 0.6.7
    Uninstalling meld3:
      Successfully uninstalled meld3
  Running setup.py install for meld3
Successfully installed django-supervisor supervisor meld3
Cleaning up...

Meine "vorhandenen Installationen" von supervisor-3.0a10 und meld3-0.6.7 werden beide "erfolgreich deinstalliert", und dann werden identische Versionen installiert.

upgrade auto-locked bug

Hilfreichster Kommentar

Ich denke nicht, dass es ein Duplikat von # 49 ist. Ich habe # 49 so gelesen, dass install -U foo _ foo selbst nicht neu installiert werden sollte, wenn es bereits in der neuesten Version ist - was sich davon unterscheidet, ob foo neu installiert werden soll oder nicht bereits erfüllte Abhängigkeiten.

Diese Unterscheidung ist wichtig für schwer zu erstellende Bibliotheken mit häufigen Releases, aber ziemlich stabilen APIs. Zum größten Teil ist eine Installation gut genug. Ich möchte sie nur neu installieren, wenn meine Abhängigkeiten neuere Funktionen von diesen verwenden verschachtelte Abhängigkeiten (dh wenn die Anforderung nicht mehr erfüllt ist) - zum Beispiel:

  • foo 0.1 hängt von lxml>=2.3.0
  • foo 0.2 wird veröffentlicht und hängt von lxml>=2.3.0 (gleiche Abhängigkeit)
  • lxml 2.4.0 wird veröffentlicht

Wenn ich bereits foo 0.1 und lxml 2.3.0 und I pip install -U foo installiert habe, möchte ich nicht, dass lxml 2.4.0 installiert wird. Es sollte nur lxml 2.4.0 installiert werden, wenn foo von lxml>=2.4.0 abhängt.

Alle 23 Kommentare

Meines Erachtens ist es ein bekanntes Verhalten, ich weiß nicht, ob es wirklich ein Fehler ist - ich denke, easy_install hat das gleiche Verhalten.

Ich würde gerne die Meinungen anderer sehen.

PS.: In StackOverflow gab es eine Frage dazu: http://stackoverflow.com/questions/5937756/why-is-pip-looking-for-download-cache-if-the-same-exact-package-is -imready-instal

Bezogen auf Ausgabe Nr. 49

Es ist ein Fehler und ein Duplikat von # 49.

Ich denke nicht, dass es ein Duplikat von # 49 ist. Ich habe # 49 so gelesen, dass install -U foo _ foo selbst nicht neu installiert werden sollte, wenn es bereits in der neuesten Version ist - was sich davon unterscheidet, ob foo neu installiert werden soll oder nicht bereits erfüllte Abhängigkeiten.

Diese Unterscheidung ist wichtig für schwer zu erstellende Bibliotheken mit häufigen Releases, aber ziemlich stabilen APIs. Zum größten Teil ist eine Installation gut genug. Ich möchte sie nur neu installieren, wenn meine Abhängigkeiten neuere Funktionen von diesen verwenden verschachtelte Abhängigkeiten (dh wenn die Anforderung nicht mehr erfüllt ist) - zum Beispiel:

  • foo 0.1 hängt von lxml>=2.3.0
  • foo 0.2 wird veröffentlicht und hängt von lxml>=2.3.0 (gleiche Abhängigkeit)
  • lxml 2.4.0 wird veröffentlicht

Wenn ich bereits foo 0.1 und lxml 2.3.0 und I pip install -U foo installiert habe, möchte ich nicht, dass lxml 2.4.0 installiert wird. Es sollte nur lxml 2.4.0 installiert werden, wenn foo von lxml>=2.4.0 abhängt.

Ah ja, das ist ein bisschen anders. Selbst wenn # 49 behoben ist, ist zusätzlicher Code erforderlich, um das gewünschte Verhalten zu erzielen, wenn die Abhängigkeit nicht die neueste Version aufweist, aber dennoch die Abhängigkeitsanforderungen erfüllt.

Ich denke, wenn wir diese Änderung vornehmen würden, würden einige Leute sie überraschend finden. Ich kann sehen, warum es in bestimmten Fällen wünschenswert ist - aber ich kann auch Fälle sehen, in denen das aktuelle Verhalten (minus # 49) vorzuziehen ist. Also bin ich in diesem Fall auf dem Zaun.

Wäre eine zusätzliche Befehlszeilenoption angemessen? pip install foo --upgrade vs pip install foo --upgrade-recursive ? (Oder --upgrade-nonrecursive wenn es wichtig ist, das aktuelle Verhalten abwärtskompatibel zu halten)

Wenn Upgrades standardmäßig nicht rekursiv sind, wird die Konsistenz mit anderen Paketmanagern wie APT und Portage gewährleistet. und ich denke, es gibt einen guten Grund für ein solches Verhalten, nämlich dass es unbeabsichtigte Nebenwirkungen vermeidet - wenn ich ein Paket P aktualisieren möchte, dann möchte ich einen Befehl in der Richtung von upgrade P eingeben, nicht upgrade P --but-not-other-things .

Andererseits denke ich, dass ein Befehl "Alle aktualisieren" (siehe # 59) standardmäßig rekursiv sein sollte, da "Alle" standardmäßig wirklich "Alle" bedeuten sollte. In diesem Fall würde nicht rekursives Verhalten bedeuten, dass "alle direkt installierten Pakete aktualisiert werden, jedoch keine Abhängigkeiten, die nicht direkt installiert wurden" (wie Portages emerge --update @world ohne --deep ).

Ein verwandtes Problem besteht darin, dass Pip fehlschlägt und das angeforderte Paket trotz Erfüllung der Abhängigkeiten nicht aktualisieren kann, wenn das zu aktualisierende Paket eine Abhängigkeit von einem anderen Paket aufweist, das bereits installiert ist, aber in einem Repository nicht verfügbar ist.

Dies scheint sowohl mit -I als auch mit -U zu geschehen.

Da -I für --ignore-installed steht und Pip so funktionieren soll, als ob derzeit nichts installiert wäre, ist die Neuinstallation von allem das richtige Verhalten für -I . Daher ist das Verhalten hier nur ein Fehler für -U , nicht für -I .

easy_install hat nicht das gleiche Verhalten. easy_install installiert Abhängigkeiten nicht erneut, wenn sie bereits erfüllt sind.

Dies ist keine Funktion oder ein Verhalten, sondern ein Fehler.

Dies ist auch sehr ärgerlich: Wenn Sie die PIP-Verteilung für ein Framework-Paket testen oder ein einzelnes Framework-Add-On aktualisieren, müssen Sie das gesamte Framework und alle seine Abhängigkeiten neu installieren. Diese unnötigen Downloads und Installationen sind Zeit- und Ressourcenverschwendung.

für diejenigen, die nur einen Weg wollen, dies _now_ zu tun, kurz vor einer Verhaltens- / Codeänderung in "-U"

Ich denke, damit wird das gewünschte Ergebnis erzielt, oder?

Aktualisieren Sie nur die Anforderungen der obersten Ebene:

  • pip install -U --no-deps REQS // aktualisiert nur die oberste Ebene
  • pip install REQS // In diesem zweiten Durchgang werden alle neuen Abhängigkeiten aus dem Upgrade installiert

Für den einfachsten Fall, der ausreicht, aber ich denke nicht, dass dies für eine request.txt-Datei funktioniert oder wenn es Abhängigkeiten gibt, deren install_requires aktualisiert wurden. Wir haben ein kompliziertes Skript, das einen Unterschied zu unseren Anforderungen macht. Txt und mehr oder weniger das, was Sie beschreiben, aber es behandelt keine Upgrade-Tiefe> 1.

Was die Sache bis zu einem gewissen Grad kompliziert, ist, dass viele Django-Pakete aufgrund dieses Fehlers ihre install_requires-Zeilen auskommentieren oder entfernen. Andernfalls wird eine Alpha-Version von Django installiert (das war unsere Erfahrung, und ich habe es in den Github-Problemen vieler bekannter Django-Pakete gesehen.

Hey @fdintino , ich habe einen Basistest mit Anforderungen, -U und --no-deps durchgeführt und es schien zu funktionieren, dh die Elemente in der Anforderungsdatei wurden aktualisiert, aber keine Abhängigkeiten. Das stimmt mit meinem Verständnis überein, was der Code tut. Es ist dort allerdings langweilig, so dass diese Idee scheitern könnte.

Für den Fall, dass eine Anforderung der obersten Ebene eine neue Abhängigkeit "install_requires" aufweist, habe ich deshalb den Befehl "2nd pass" erwähnt, um diese zu installieren.

Für den Fall, dass es "Abhängigkeiten gibt, deren install_requires aktualisiert wurden", bin ich mir nicht sicher, ob ich Ihnen dort folge. Sie würden das nur entdecken und darauf reagieren wollen, wenn Sie ein vollständiges rekursives Upgrade durchführen möchten, oder?

Nur wenn Sie die Anforderungen nicht mehr erfüllt haben. Wenn ich zum Beispiel Django-Sentry aktualisiert habe und Django-Sentry django-celery>=2.5.4,django-celery<3.0 wo zuvor django-celery>=2.5.3,django-celery<3.0 erforderlich war (möglicherweise aufgrund einer Fehlerbehebung oder einer neuen Funktion), habe ich dies derzeit getan django-celery==2.5.3 , dann würde ich erwarten, dass Django-Sellerie aktualisiert wird, um die Anforderungen zu erfüllen, so wie es mein Patch tut. Wenn ich jedoch django-celery==2.5.4 hätte, würde ich nicht erwarten, dass es Sellerie aktualisiert. Im Fall von Sellerie ist dies keine große Sache, aber wenn Pakete Django>1.2,Django<=1.4 haben und Projekte häufig auf Django 1.2, 1.3 oder 1.4 geschrieben werden, kann ein unerwartetes Upgrade von Django große Kopfschmerzen verursachen.

danke @fdintino . Ich folge jetzt. Sie möchten nicht jedes rekursive Verhalten abschneiden (das die erforderlichen Upgrades zur Erfüllung der Anforderungen ausführt), sondern nur rekursive "erzwungene" Upgrades stoppen.

Übrigens wird Ihr Kommentar aufgrund der Formatierung abgeschnitten. Vielleicht möchten Sie das für andere beheben.

Ich habe eine Übersicht veröffentlicht, in der die Erreichung des gewünschten Verhaltens mithilfe der beiden oben genannten Befehle beschrieben wird.
Nicht, dass dies den Wunsch nach diesem Ticket oder dem Pull ungültig macht, aber es war mir hilfreich zu bestätigen, wie
es funktioniert aktuell und was aktuell möglich ist.
(Hinweis: Im Beispiel ist "b" die Parallele zu Django, die als Problem erwähnt wurde.)

https://gist.github.com/3088149

Kommentar im Kern geschätzt, wenn dies nicht das Szenario ist.

Ich stelle fest, dass dies schon lange offen ist.

Ich habe festgestellt, dass meine Version von pip jetzt die Option dazu hat

pip install --upgrade --upgrade-strategy=only-if-needed package

Dies scheint das gewünschte Verhalten zu sein, wenn auch ziemlich ausführlich. Persönlich denke ich, dass es großartig gewesen wäre, wenn dies die Standardeinstellung wäre, aber vielleicht ist es zu spät, um sie jetzt zu ändern.

Wenn es zu spät ist, die Standardeinstellung zu ändern, kann dies meiner Meinung nach geschlossen werden?

In https://github.com/pypa/pip/issues/3871#issuecomment -247789343 habe ich erwähnt, wie wir dies meiner Meinung nach vorantreiben werden, und hier wiedergegeben:

Kreisen Sie jetzt darauf zurück. Ich denke, wir sollten Folgendes tun:

  1. Fügen Sie --upgrade-Strategy = [eifrig / nicht eifrig] in pip vX hinzu, das standardmäßig eager , und ermöglichen Sie den Benutzern, sich für die nicht eifrige Strategie zu entscheiden. Auf diese Weise können wir einige reale Tests von Menschen erhalten, ohne dass jeder gleichzeitig eine Änderung erzwingen muss.
  2. Sobald wir alle Rückmeldungen von 1. beantwortet haben, ändern Sie in pip vX + 1 den Standardwert von --upgrade-strategy auf non-eager . Dies wird uns viel Nutzen aus der realen Welt bringen, indem wir allen eine Veränderung aufzwingen, aber es gibt eine Notluke für Menschen, die aus irgendeinem Grund durch die Veränderung gebrochen werden.
  3. Wenn wir Rückmeldungen von 2. beantwortet haben, sehen Sie sich an, wie --upgrade-strategy in pip vx + 2 verworfen wird (um gemäß unserer normalen Verfallsrichtlinie entfernt zu werden).

Dies hat eine längere Vorlaufzeit, bevor nicht-eifrig die Standardeinstellung ist, aber es ermöglicht uns, sie langsamer einzuführen, um sicherzustellen, dass es keinen Anwendungsfall gibt, der davon abweicht. Idealerweise denke ich, wir möchten irgendwann die --upgrade-strategy -Flagge loswerden. Diese Art von Flag fühlt sich so an, als würde es nur um Probleme mit kaputten Dingen bitten, da wir im Wesentlichen unsere Upgrade-Tests duplizieren müssen, um die Dinge tatsächlich vollständig zu testen. Ich denke, es ist eine gute Flagge, die man vorerst hinzufügen sollte, um die Phase zu ermöglichen und eventuelle Brüche zu beheben.

Okay, hört sich gut an. Ich werde warten, bis Schritt 2 abgeschlossen ist. Scheint, dass das andere Problem ein Duplikat ist, aber bereits geschlossen.

@xavfernandez @dstufft Kann dies geschlossen werden oder warten wir, bis der Standard wechselt?

Wir werden wahrscheinlich warten, bis der Standard wechselt.

Schließen, da # 4500 zusammengeführt wurde

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen