
Am 24.03.2017 um 20:20 schrieb Christopher Arndt:
Hallo Thomas und andere Interessierte,
Am 23.03.2017 um 12:07 schrieb Thomas Güttler:
Ich verstehe nicht so richtig warum dieser Ablauf von pip-tools[1] verwendet wird.
ich fange mal mit einer allgemeinen Antwort auf deine letzte Frage an:
Warum sollte man mit den pip-tools die req.txt Dateien aktualisieren?
* Es müssen in den Eingabe-Dateien nur idR die direkten Abhängigkeiten definiert werden. * Die erzeugten Requirements-Dateien pinnen direkte und indirekte Abhängigkeiten. * Beim Erstellen der Requirements wird sichergestellt, dass die gepinnten Versionen auch verfügbar sind, ... * ... und dass der geforderte Abhängigkeitsgraph auflösbar ist, ... * und dies auch bei Requirements-Dateien, die von einander abhängen, z.B. 'production.txt'->'base.txt' und 'dev.txt'->'base.txt' * Man kann die geforderten Versionen einzelner Dependencies ändern, ohne dass das unbeabsichtige Änderungen bei anderen Abhängigkeiten hat.
Ich sehe das so: in setup.py install_requires sind die ungenauen Abhängigkeiten eingetragen (kein Pinning).
irgendwie ist es eine endlose Quelle von Verwirrungen, dass es in der Python Welt zwei Wege für die Definition von Abhängigkeiten gibt (setup.py/install_requires und req.txt).
"ungenauen" ist etwas ungenau :) In den "install_requires" werden die abstrakten Abhängigkeiten festgelegt, die die Software braucht. D.h. hier dürfen idR keine festen Versionen gepinnt werden (!) sondern höchstens Mindestversionen und u.U. Maximalversionen der Abhängigkeiten.
ok. Hier sind wir 100% einer Meinung. Genau das meinte ich mit "ungenau".
Die install_requires werden verwendet, wenn aus der Software ein (TGZ, Wheel, Egg)-Paket gebaut wird und dieses dann via easy_install oder pip installiert wird. Hast du nun eine Anwendung X, und diese will Paket A und B installieren, und Paket A hat in seiner setup.py stehen 'install_requires = ["C==1.0"]' und Paket B hat in seiner setup.py stehen 'install_requires = ["C==2.0"]' kommmt es zu einem Versionskonflikt: die Abhängigkeiten deiner Software lassen sich nicht mehr installieren.
In den Requirements-Dateien dagegen stehen nicht die Abhängigkeiten deiner Anwendung, sondern eine mögliche Lösung des Abhängigkeitsgraphen. Diese stellt eine Beschreibung der Python-Umgebung für deine Anwedung dar (Pythonversion, Rechner-Architektur, und OS jetzt mal außen vor gelassen). Dieser Stand wird installiert, gegen diesen laufen die Tests und diesen will man auf dem Produktionssystem gleichermaßen herstellen. Das heisst, in den Requierements-Dateien will ich die genauen Versionen aller Abhängigkeiten pinnen, denn nur für diese ist getestet, dass sie sich alle gemeinsam installieren lassen und nur gegen diese sind die Ergebnisse der Tests valide.
Ja, genau. Die req.txt ist einen Lösung des Abhängigkeitsgraphen.
Dann läuft das CI und wenn alles ok ist, dann wird eine req.txt per "pip freeze" erstellt. Dies erstelle req.txt enthält dann das Ergebnis des CI: dieser Stand (alles version-pinned) ist erfolgreich getestet worden.
Ja, aber wenn du dann die Version einer Dependency aktualisieren willst, was machst du dann?
Das erhöhen der Version einer Dependency mache ich ja nicht aus Spaß an der Freude. Dafür gibt es Gründe. Ich passe das Modul an, dass die höhere Version braucht. Wie ich das mache? Ich erhöhe die >= Angabe von der install_requires-Zeile in setup.py Für mich sollte req.txt nur das Ergebnis von CI sein. Ich stelle mir mal diesen Graph vor: ProjektFoo -> libbar -> libsub Wenn etwas in ProjektFoo schief geht, weil libsub noch in Version 0.1 ist, und es in Version 0.2 klappt. Dann steht man vor der Frage: Was tun? Das ist dann abzuwägen. Strategie1: libbar Abhängigkeit erhöhen. Strategie2: ProjektFoo bekommt eine Abhängigkeit zu libsub. Aus meiner Sicht sind beide Wege plausibel. Das ist im Einzelfall zu betrachten. Ich bin großer Freund von zwei Dingen, die super langweilig und nahezu narkotisierend einschläfernd wirken: SQL und EVA Mit EVA meine ich: Eingabe-Verarbeitung-Ausgabe. Meine Sichtweise: Eingabe für das CI ist install_requires aus setup.py Dann kommt die Vearbeitung im CI. Dann kommt das Ergebnis: Fall1: Mindestens ein Test ist fehlgeschlagen. Fall2: Alles prima: req.txt wurde erstellt. Mit dieser Liste von Software klappt es. Im ehrlich zu sein ist bei uns derzeit im Input auch eine req.txt Datei. Das ist aber nur weil so weit ich weiß in install_requires nicht ein "git+https://..." stehen kann.
* Trage ich die neue Version einfach in die Requierements-Datei ein, ist nicht sichergestellt, dass sich die neue Version überhaupt mit den sonstigen Versionen, die in der Requirementsdate gepinnt sind, installieren lässt.
Ich wüsste nicht warum ich in Requirements-Datei per Hand Änderungen machen sollte.
* Installiere ich die neue Version einfach mit "pip install -U XYZ", werden höchstwahrscheinlich weitere Abhängkeiten aktuaisiert und es findet keine Prüfung statt, ob deren neue Versionen mit meiner Anwendung kompatibel sind. Wo sollte eine solche Einschränkung dokumentiert werden?
Sicherlich kann man im Entwicklungssystem "pip install -U xyz" machen. Aber wo wird das Ergebnis notiert? Es wird ja nur die virtualenv angepasst. Wenn ich danach "git diff" auf allen Repos ausführen ... dann gibt's nichts zu commiten. Auf jeden Fall ist das so in meinem Umfeld. Das CI zieht sich alles aus dem git ....
* Installiere ich die neue Version mit "pip install -U --no-deps XYZ", bekommme ich mit einem "pip freeze" danach einen Stand meiner Umgebung, der sich u.U. gar nicht mehr mit "pip install -r requirements.txt" installieren lässt, weil die gepinnten Versionen nicht mehr zum Abhängigkeitsgraphen passen.
Mit pip-tools erhöhe ich einfach die Mindestversion der Abhängigkeit in der requirements.in Datei, lasse dann nochmal pip-compile laufen und habe danach eine valide requirements.txt Datei oder bekomme eben gleich einen Fehler und weiß, dass die Abhängigkeiten nicht zusammen passen (und nicht erst, wenn versucht wird, "pip install -r ..." im CI oder gar erst auf dem Staging/Produktionssystem auszuführen).
Ich hoffe, ich habe die Problematik damit etwas verdeutlichen können. Hier noch der Link zu einem interessanten Blog-Artikel über einen guten Workflow für pip-tools: ..
Ja, mir ist etwas klarer geworden wie du arbeitest. Gruß, Thomas -- http://www.thomas-guettler.de/