Pip: Beheben von Problemen im Zusammenhang mit Out-of-Tree-Builds

Erstellt am 4. Jan. 2020  ·  68Kommentare  ·  Quelle: pypa/pip

Ich öffne dieses Thema als Versuch, die Diskussion über Out-of-Tree-Builds, die damit verbundenen Probleme und mögliche Lösungen zu konsolidieren.

Welches Problem wird diese Funktion lösen?

Wenn Sie Projekte aus lokalen Verzeichnissen erstellen, kopiert pip diese zuerst

Dieser Ansatz hat im Laufe der Zeit eine Reihe von Problemen aufgeworfen:

  • Wenn setup.py / pyproject.toml sich nicht im Stammverzeichnis des Projekts befindet und wenn der Build von Ressourcen außerhalb des Unterbaums setup.py / pyproject.toml abhängt (#3500, #7549, #6276), zB:

    • build benötigt Ressourcen, die symbolische Links zu Dateien/Verzeichnissen außerhalb des Unterbaums sind

    • build benötigt das Git-Repository (zB wenn setuptools_scm verwendet wird), und .git/ ist in einem übergeordneten Verzeichnis, das nicht von pip in das temporäre Verzeichnis kopiert wird

    • build basiert auf dem Unterverzeichnisnamen (vielleicht etwas exotisch, aber ich habe einen Fall, in dem ich ein benutzerdefiniertes Build-Backend erstellen möchte und ein Teil der Metadaten vom Unterverzeichnisnamen abhängt)

  • Leistungsprobleme, wenn das Projektverzeichnis groß ist (#2195).

Warum kopiert pip vor dem Erstellen in ein temporäres Verzeichnis? Vorbehalt: Das ist mir unklar - das habe ich bisher gesammelt:

  • Um zu vermeiden, sich auf etwas außerhalb des Quellcodes zu verlassen (https://github.com/pypa/pip/issues/2195#issuecomment-524606986) - obwohl die Definition von "Out of Source" die Ursache für einige der oben genannten Probleme ist
  • Um eine Verschmutzung des Quellverzeichnisses mit Build-Artefakten oder Rückständen zu vermeiden (?)
  • Etwas anderes?

Mögliche Lösungen

  1. Bauen Sie ein sdist an Ort und Stelle, entpacken Sie das sdist an einem temporären Ort und bauen Sie dann daraus.
  2. Fügen Sie eine Pip-Option hinzu, um an Ort und Stelle zu bauen.
  3. Aktualisieren Sie PEP 517 mit einer Art Mechanismus, damit Back-Ends mit Front-Ends kommunizieren können, wenn sie für In-Place-Builds "sicher" sind.
  4. Ändern Sie Pip, um immer an Ort und Stelle zu bauen.
  5. Ändern Sie pip so, dass es standardmäßig an Ort und Stelle erstellt wird, mit einer Option zum Erstellen außerhalb des Baums.

Zusätzlicher Kontext

Weitere Diskussionen zum Bauen über sdist auf Discussion.python.org .

needs discussion

Hilfreichster Kommentar

Von https://github.com/pypa/pip/issues/2195#issuecomment -664728481 kann ich sagen, dass ich mehr als glücklich bin, #7882 hinter --use-feature=in-tree-build zu wiederholen.

Alle 68 Kommentare

Betrachtet man dies aus der Perspektive des Backends, ist die Idee eines "Out-of-Tree-Builds" eigentlich bedeutungslos. Das Backend erhält einen "Quellbaum" in Form des aktuellen Verzeichnisses des Prozesses und wird aufgefordert, einen Build auszuführen. Es hat keine Möglichkeit zu wissen, ob dieses Verzeichnis aus einem sdist extrahiert, aus einem VCS ausgecheckt oder von woanders kopiert wurde. Alles, was es tun kann, ist zu bauen, und wenn es nicht über das verfügt, was es zum Erstellen benötigt, melden Sie Fehler.

Das tötet die mögliche Lösung (3) IMO - das Backend hat kein Konzept dafür, was ein In-Place-Build ist , daher kann es nicht sagen, ob ein solcher Build sicher ist 1 .

Was (2) angeht, bin ich generell gegen zusätzliche Optionen wie diese. Wenn wir wissen, was am besten zu tun ist, sollten wir es tun, und wenn nicht, dann ist die Weitergabe des Problems an den Benutzer keine besonders freundliche Option. Das Problem hier ist subtil genug, dass ich erwarten würde, dass nur wenige Benutzer wissen, was die richtige Wahl ist, daher würden wir wahrscheinlich sehen, dass Leute nur die beiden Optionen ausprobieren und blindlings "was auch immer funktioniert" verwenden. Außerdem sind die Auswirkungen auf den Support erheblich. Das Anbieten einer Option bedeutet eindeutig, dass wir zumindest in einigen Fällen davon ausgehen, dass die Build-Ergebnisse unterschiedlich sind. Wie können wir also testen, ob die Unterschiede unseren Erwartungen entsprechen? Sind wir dafür verantwortlich, Benutzer darüber aufzuklären, wann das Flag für den In-Place-Build benötigt wird oder nicht (entweder über unsere Dokumentation oder aufgrund von Problemen, die von Benutzern angesprochen werden, die nicht wissen, welche sie verwenden sollen)?

Trotzdem bin ich nicht dagegen, dass Pip einfach an Ort und Stelle baut. Ich glaube, der Grund, warum wir das nicht tun, ist, dass wir Fälle hatten, in denen Artefakte, die von einem vorherigen Build übrig geblieben sind, in einem nachfolgenden Build verwendet wurden, aber mit anderen Optionen erstellt wurden (z vom gleichen Baum). Es ist jedoch vernünftig zu sagen, dass Backends sicherstellen sollten, dass solche Probleme nicht auftreten. Ich bin mir jedoch nicht sicher, ob eine solche Haltung besonders benutzerfreundlich ist - dies kam während der PEP 517-Diskussionen zum Thema inkrementelle Builds auf und war so umstritten, dass es damals verschoben wurde.

Meine Vorliebe war es, seit langem ein sdist zu bauen und dann das Rad daraus zu bauen (Ihre Option 1). Ich bin mit dem Pip-Building einverstanden (wenn wir uns darauf einigen können, dass dies sicher ist, da wir, wie oben erwähnt, nicht erwarten können, dass das Back-End uns dies mitteilt), aber ich denke, das würde eine Community brauchen Diskussion, um die weiteren Auswirkungen (auf Backends, Pip/Frontends und Endbenutzer) auszuloten.

1 Es wäre natürlich möglich, PEP 517 zu aktualisieren, um zu festzulegen .

Ich habe die Lösungen 4. (Ändern Sie pip so, dass es immer an Ort und Stelle erstellt wird) und 5. (Ändern Sie pip so, dass es standardmäßig mit einer Option zum Erstellen außerhalb des Baums erstellt wird).

Ich habe gemischte Gefühle beim Bauen über sdist (Lösung 1.) aus folgenden Gründen:

  1. einige Projekte haben möglicherweise einen unterbrochenen Pfad von sdist-to-Wheel; Ich sehe zwar den Wert der Validierung, dass das Erstellen von sdists funktioniert, aber es jetzt standardmäßig zu tun, wird sicherlich viele Endbenutzer-Builds zerstören
  2. es hat immer noch Auswirkungen auf die Leistung bei Projekten mit großen sdists und aufgrund zusätzlicher Unterprozessaufrufe
  3. Ich persönlich denke, wir sollten nicht zu viel Wert auf sdists legen, da es bei Projekten durchaus üblich ist, gebaute Artefakte zu veröffentlichen und sich für ihre Quellversionen auf ihre bevorzugte Code-Hosting-Plattform zu beziehen (z Gebäude müssen durch Reifen springen, um einen funktionierenden sdist zu produzieren). Und PEP 517 ermöglicht es Backends speziell, UnsupportedOperation für build_sdist zu erhöhen.

Dieser Beitrag zum Thema "Diskussieren" fasst auch ähnliche Argumente zusammen.

Ich stimme zu, dass der Weg für Lösung 3 alles andere als offensichtlich ist.

Ich stimme auch zu, dass wir zusätzliche Optionen vermeiden sollten, wenn wir können.

Ich stelle auch fest, dass es im verlinkten Diskussionsthread einige Stimmen für In-Place-Builds gab, aber in der Tat ist eine fokussierte Community-Diskussion zu diesem speziellen Thema erforderlich, wenn wir diesen Ansatz untersuchen möchten.

  • Bauen Sie ein sdist an Ort und Stelle, entpacken Sie das sdist an einem temporären Ort und bauen Sie dann daraus.

Ich denke, das ist ein guter Ansatz.

IMO-Chancen stehen gut, dass dies für ein einzelnes Paket in den meisten pip install -Ausführungen mit lokalen Verzeichnissen ausgeführt wird - am häufigsten stelle ich mir pip install . . Dies würde wahrscheinlich als Teil des Paketentwicklungsworkflows erfolgen.

Ich denke, dieses Verhalten sollte wie folgt aussehen:

  • Wenn das Backend kein sdist erstellen kann, tun Sie local-dir -> wheel (in-place)

    • Ich denke, die Verantwortung liegt sehr beim Backend, um sicherzustellen, dass local-dir -> wheel in diesem Fall eine idempotente Operation ist.

  • Wenn das Backend in der Lage ist, ein sdist zu erstellen, tun Sie local-dir -> sdist -> unpacked-sdist -> wheel.

Wenn wir local-dir -> sdist -> wheel ausführen, haben wir einen zusätzlichen Satz von Aufrufen. Ich denke jedoch, dass es vernünftig ist, zu überprüfen, ob generierte sdists vernünftig sind, insbesondere während der Entwicklung. tox macht dies bereits als Teil seines Workflows, Check-Manifest, um die nicht so benutzerfreundlichen Schnittstellen von setuptools hier abzudecken.

Insgesamt denke ich, dass sich die Kosten für die Erstellung eines sdist bei einem lokalen Verzeichnis lohnen, um solche Fehler in Projekten zu vermeiden, insbesondere da Leute, die aus lokalen Verzeichnissen installieren, wahrscheinlich die Entwickler des Projekts selbst sind.

Was den Rollout angeht, sollten wir abwarten und beobachten, wie #6536 auf den Markt kommt. Wir würden auf jeden Fall ein paar Dinge lernen, die übertragen werden können.

Ich ziehe den Bau / ohne Sdist an Ort und Stelle zu installieren (so setup.py install oder setup.py bdist_wheel oder Aufruf build_wheel als anwendbar auf dem PEP 517 Back - End) vs einem Sdist Aufbau, Auspacken und Installieren davon. Meine konkreten Gründe sind:

  1. Unterstützt die größte Anzahl von Benutzern, die sofort einsatzbereit sind.

    1. Angenommen, pip macht local-dir -> installiert (über Wheelbuild in-place oder setup.py install ). Benutzer, die von local-dir -> installiert gehen möchten, können pip install local-dir ausführen. Benutzer, die von local-dir -> sdist -> installiert gehen möchten, können ein sdist erstellen und dann pip install ./path/to/sdist ausführen. Es gibt viele alternative Tools, die einen sdist erstellen können, und dies ist etwas, das Benutzer wahrscheinlich bereits haben werden, es sei denn, sie erstellen die Distributionen, die sie auf PyPI hochladen, von Hand.

    2. Nehmen Sie nun an, dass pip local-dir -> sdist -> installiert macht. Benutzer, die von local-dir -> installiert gehen möchten, haben keine Optionen, die pip beinhalten. Benutzer, die von local-dir -> sdist -> installiert gehen möchten, können pip install local-dir ausführen. Die Benutzer ohne Optionen fragen pip nach Optionen zur Steuerung des Verhaltens oder müssen ein anderes Tool finden, das sie sonst nicht benötigt hätten.

  2. Wenn wir local-dir -> sdist -> installiert implementieren, würden wir dies vermutlich auch für VCS-basierte Anforderungen tun? Wenn ja, ist das mehr Arbeit. Wenn nicht, sind das zusätzliche Pfade durch den Code und Abweichungen in der Handhabung der Installation, die von Benutzern oder bei der Bereitstellung von Support beachtet werden müssen.
  3. Am wenigsten zu implementieren. Es gibt drei Stellen, die geändert werden müssen, um local-dir -> installiert zu implementieren ( hier , hier und hier ). Für local-dir -> sdist -> installiert würde ich die Implementierung nicht einmal berühren, bis #6607 fertig ist, sonst würde es meiner Meinung nach an vielen Stellen in der Codebasis enden, ähnlich wie beim Herunterladen von Artefakten / Hash-Überprüfung.
  4. Geringster Arbeitsaufwand zum Testen, da, IMO, vorhandene Tests ausreichen, um den Pfad local-dir -> installierter Code abzudecken. Für den Pfad local-dir -> sdist -> installiert möchten wir überprüfen, ob wir tatsächlich einen sdist erstellen und dass die Fallbacks zum direkten Erstellen eines Rads funktionieren.
  5. Geringster Arbeitsaufwand (rechnerisch). Wie an anderer Stelle erwähnt, ist local-dir -> sdist -> installed ein zusätzlicher Unterprozessaufruf (und dieser Unterprozess verrichtet Arbeit). Es bedeutet auch, dass pip den sdist (Hallo Virenscanner und ansonsten langsame Festplatten) entpacken muss, bevor er den Radbau durchführt.

Unabhängig von der Herangehensweise ist das einzige Problem, das ich bei der Durchführung von Dingen an Ort und Stelle sehe, dass wir bei Setuptools-Builds (ich denke, dies gilt für Legacy und PEP 517) am Ende .egg-info im Projektverzeichnis landen, was falsch wird als "installiertes Paket", wenn pip mit python -m pip in diesem Verzeichnis aufgerufen wird. Dies würde durch #4575 behoben, das das aktuelle Verzeichnis vermutlich NICHT in die Abfrage nach installierten Paketen für jedes Schema einbeziehen würde.

Ich habe festgestellt, dass ich zustimme, dass die Idee, den sdist-Build zu überspringen und direkt einen In-Tree-Build durchzuführen, ein besserer Ansatz für pip ist, um standardmäßig zu gehen, und nicht zu versuchen, local-dir -> sdist -> wheel zu tun.

Wenn wir in Fedora Python-RPM-Pakete erstellen, sind wir Dinosaurier und der Standardweg ist die Verwendung von python setup.py build . Mit PEP 517 haben wir stattdessen eine "vorläufige" Möglichkeit hinzugefügt, pip wheel verwenden. Bei Erweiterungsmodulen haben wir jedoch ein Problem mit dem Ansatz "Quellen nach tmp verschieben, von dort erstellen", den pip verwendet, um sie zu erstellen.

Unsere Build-Maschinerie fügt einige Compiler-Flags ein, sodass die Build-Artefakte (in diesem Fall .so Erweiterungsmodule) Metadaten über ihre Quellen enthalten. Später gibt es ein Shell-Skript, das die Build-Artefakte durchläuft, diese Informationen extrahiert und die Quellen nach /usr/src/debug kopiert, um sie über ein spezielles *-debugsource RPM zu installieren. Die Maschine erwartet, dass alles innerhalb des Arbeitsbaums gebaut wird und es funktioniert nicht wirklich gut, wenn es draußen gebaut wird. Hier sind die Dinge, die (gemeinsam) getan werden können, um das Problem auf unserer Seite zu mildern:

  1. Legen Sie die Umgebungsvariable $TMPDIR , dass sie sich an der Stelle befindet, an der das RPM-Skript sie erwartet (dh export TMPDIR=%{_builddir}/.tmp (und erstellen))
  2. Verwenden Sie pip wheel mit der Option --no-clean , um die kopierten Quellen in $TMPDIR zu behalten
  3. Führen Sie etwas Shell-Kung-Fu aus, um die "Was ist meine Quelle"-Information an den richtigen Ort zu schreiben: find %{buildroot} -iname '*.so' -print0 | xargs --no-run-if-empty -0 -n1 /usr/lib/rpm/debugedit -b "%{_builddir}/.tmp/pip-req-build-"* -d "$PWD"
  4. (Optional: $TMPDIR manuell reinigen.)

Der dritte Schritt gefällt uns nicht besonders, da er auf zu vielen Implementierungsdetails angewiesen ist:

  • /usr/lib/rpm/debugedit API und Standort (und Existenz)
  • der pip-req-build Name
  • der Mechanismus, mit dem Pip die Quellen baut

Wenn pip immer an Ort und Stelle gebaut würde oder wenn es dafür einen Befehlszeilenschalter gäbe, würde das Problem verschwinden.

Downstream-Bericht: https://bugzilla.redhat.com/show_bug.cgi?id=1806625

Ich habe festgestellt, dass ich zustimme, dass die Idee, den sdist-Build zu überspringen und direkt einen In-Tree-Build durchzuführen, ein besserer Ansatz für pip ist, um standardmäßig zu gehen, und nicht zu versuchen, local-dir -> sdist -> wheel zu tun.

Ich neige auch immer mehr dazu, die Idee eines In-Place-Radbaus zu akzeptieren. Meine restlichen Reservierungen sind:

  1. Wir würden uns darauf verlassen, dass sich das Backend "richtig" verhält - zB keine anderen Ergebnisse basierend auf übriggebliebenen Daten aus früheren Builds oder was auch immer liefert. Ich bin mit dieser Annahme einverstanden, aber ich mache mir Sorgen über die Supportkosten, wenn wir anfangen, Leute dazu zu bringen, zu sagen "Pip hat mein Rad falsch gebaut" und wir müssen nur debuggen, um festzustellen, dass es sich um ein Backend-Problem handelt.
  2. Ich denke, wir sollten jeden Ansatz, den wir verfolgen, sehr klar und explizit dokumentieren und uns stark bemühen, vollständig darauf überzugehen. Wir möchten pip wirklich keinen "noch weiteren Ansatz" hinzufügen, während wir den gesamten alten Code aus Kompatibilitätsgründen beibehalten. Wenn wir uns nicht auf den neuen Ansatz festlegen können, führen wir nur noch mehr Wartungsprobleme ein.
  3. Als Folge davon sollten wir uns vergewissern, dass es keine uns bekannten Projekte gibt, die auf unserem aktuellen "Copy and Build"-Ansatz beruhen, da wir sie mit dieser Änderung brechen werden.

... und natürlich muss jemand eine PR schreiben, die diese Änderung implementiert (mit Tests, Dokumenten usw. - das Übliche) sonst reden wir nur

Wir würden uns darauf verlassen, dass sich das Backend "richtig" verhält - zB keine anderen Ergebnisse basierend auf übriggebliebenen Daten aus früheren Builds oder was auch immer liefert. Ich bin mit dieser Annahme einverstanden, aber ich mache mir Sorgen über die Supportkosten, wenn wir anfangen, Leute dazu zu bringen, zu sagen "Pip hat mein Rad falsch gebaut" und wir müssen nur debuggen, um festzustellen, dass es sich um ein Backend-Problem handelt.

Wäre es sinnvoll, die PEP 517-Schnittstelle um einen „sauberen“ Hook zu erweitern? Wir würden es wahrscheinlich sowieso irgendwann wollen, um andere Bemühungen zu ermöglichen (zB bearbeitbare Installation implementieren, ein Paketentwicklungstool erstellen, das jedes PEP 517-Projekt erstellt). pip kann es hier aufrufen, um sicherzustellen, dass kein Junk übrig ist, bevor der Build im Baum ausgeführt wird.

Wäre es sinnvoll, die PEP 517-Schnittstelle um einen „sauberen“ Hook zu erweitern?

Vielleicht? Aber wenn pip automatisch clean aufruft, gibt es bestimmt jemanden, der dies nicht möchte, inkrementelle Builds oder so. Und dann haben wir am Ende eine andere Option.

Meine Neigung ist, bei meiner Position zu bleiben: "Wir müssen in der Lage sein, davon auszugehen, dass es in der Verantwortung des Backends liegt, sicherzustellen, dass In-Place-Builds korrekt funktionieren". Selbst wenn sich das als unhaltbar herausstellt, helfen uns konkrete Beispiele dafür, warum es nicht funktioniert, besser zu verstehen, was wir mit dem Problem tun können, anstatt nur zu raten.

  1. Wir würden uns darauf verlassen, dass sich das Backend "richtig" verhält - zB keine anderen Ergebnisse basierend auf übriggebliebenen Daten aus früheren Builds oder was auch immer liefert.

Ich wäre versucht, PEP-517 zu erweitern, um dies zu einer expliziten Anforderung zu machen.

Ich wäre versucht, PEP-517 zu erweitern, um dies zu einer expliziten Anforderung zu machen.

Das sagt es schon:

Das Back-End kann Zwischenartefakte in Cache-Speicherorten oder temporären Verzeichnissen speichern. Das Vorhandensein oder Fehlen von Caches sollte keinen wesentlichen Einfluss auf das Endergebnis des Builds haben.

Es ist nicht so sehr wahrscheinlich, dass Backends diese Anforderung absichtlich verletzen, da Benutzer das Problem natürlich als Pip-Problem melden und zum Backend-Projekt weitergeleitet werden, was ein bisschen zusätzlicher Aufwand ist.

Beim Versuch, eine Problemumgehung für Fedora zu finden, wurden wir von https://github.com/pypa/pip/issues/7872 getroffen

Da wir das Problem ".egg-info in cwd" mit #7731 und Freunden behoben haben, ist dies eine Sache weniger, um die Sie sich beim Bauen Sorgen machen müssen.

Also wurde Option 4 (immer eingebaut) in #7882 implementiert.

Wir haben jetzt (gemäß #7951) eine Betaversion von pip veröffentlicht, pip 20.1b1. Diese Version enthält #7882, die eine Lösung für dieses Problem implementiert hat.

Ich hoffe, dass die Teilnehmer dieser Ausgabe uns helfen werden, indem sie die Beta testen und nach neuen Fehlern suchen. Wir möchten mögliche Probleme vor dem Hauptrelease 20.1 am Dienstag identifizieren und beheben.

Ich freue mich auch über positive Rückmeldungen nach dem Motto "yay, es funktioniert jetzt besser!" auch, da der Issue Tracker normalerweise voller "Probleme" ist. :)

Wir planen total, es in Fedora zu testen (wir haben das bereits vor Ihrem Kommentar geplant), aber die Frist für Dienstag ist wahrscheinlich nicht realistisch.

@hroncok Irgendeine Idee, bis Fedora diese Änderungen testen kann?

Ich werde versuchen, es am Montag irgendwie zu schaffen, kann aber keine Versprechungen machen.

Tatsächlich lässt 20.1b1 unsere Probleme verschwinden.

Allgemeineres 20.1b1-Feedback in https://mail.python.org/archives/list/[email protected]/message/5EAUIYYIRKXEHTAG5GQ7EJHSXGZIW2F7/

Hurra! Vielen Dank für das Ausprobieren der Beta @hroncok! Sehr geschätzt! ^>^

Ein Ergebnis von Build-in-Place: Ich hatte parallel Räder für mehrere Python-Versionen gebaut (in einem Manylinux-Docker-Container). Bei In-Place-Builds funktionieren parallele Builds nicht, da die verschiedenen Versionen in Konflikt geraten. Bei Out-of-Tree-Builds erstellte jede Version einen separaten Baum und hatte kein Problem.

@manthey diese Diskussion ist unter #8168

Es ist also mehr als 10 Tage her. Es wurden einige Probleme bezüglich der Änderung angesprochen (alles erwartet, würde ich sagen - #8165, #8168, #8196). Es gab auch Leute, die ausdrücklich erwähnten, dass die Veränderung ihnen hilft.

  • Neben Leistungsproblemen hatte das vorherige Verhalten (in temporäres Verzeichnis kopieren) Korrektheitsprobleme (oben verlinkt), die ohne Kontextwissen, das nur der Aufrufer hat (und als Randnotiz, der Copytree-Code bereits voll war) nicht per pip behoben werden können Pflaster, um mit seltsamen Situationen fertig zu werden - tmpdir im Baum, Steckdosen usw.).
  • Eine Option zum Aktivieren des vorherigen Verhaltens würde immer noch die Korrektheits- und Leistungsprobleme haben.
  • Eine korrekte Lösung beinhaltet Build-Back-End-Unterstützung, um das Build-Verzeichnis zu kontrollieren, das heute nicht vollständig existiert (zum Beispiel hat setuptools bdist_wheel --bdist-dir , schreibt aber immer noch .egg-info in siehe auch https://github.com/pypa/setuptools/issues/1816, https://github.com/pypa/setuptools/issues/1825). Nun, da sich pip korrekt verhält, kann sich die Diskussion vielleicht verschieben, um zu sehen, ob zB setuptools eine Option entwickeln kann, um einen Build durchzuführen, ohne das Quellverzeichnis zu berühren, und dann zu prüfen, ob eine PEP 517-Änderung erforderlich ist oder diese Option nicht steuert.
  • In der Zwischenzeit sind die gemeldeten Probleme wahrscheinlich für Anrufer relativ einfach zu umgehen (zB indem sie sich selbst in ein temporäres Verzeichnis kopieren oder einen temporären Tarball erstellen, was sie bei voller Kenntnis des Kontexts korrekt ausführen können).
  • Schließlich ist es mit den uns vorliegenden Daten schwer zu sagen, aber meine Intuition ist, dass diese Änderung mehr Menschen hilft, als sie schmerzt.

Ich hasse es also, Änderungen zu durchbrechen, aber dieser wurde nicht leichtfertig gemacht, und aus diesen Gründen neige ich persönlich dazu, ihn beizubehalten.

Ich stimme nicht zu, dass sich das neue Verhalten "richtig", sicher anders verhält und anscheinend in einigen Fällen anders gebrochen ist, und ich denke, es ist falsch, es als solches zu formulieren. Es stellt einen Kompromiss für eine Gruppe von kaputten Benutzern für eine andere Gruppe dar. In beiden Fällen gab es hier Abhilfen, die durchgeführt werden konnten.

Ich hätte diese Änderung nicht zusammengeführt und hätte sie verpasst, oder ich hätte dagegen argumentiert (und ich denke, dass es jetzt, nachdem sie zusammengeführt wurde, es einigen macht, pip als Zwangsfunktion zu verwenden, um zu helfen, bestimmte Arten von kaputten Paketen zu verhindern, erheblich schwieriger ). Davon abgesehen weiß ich nicht wirklich, ob hier ein Zurücksetzen das Richtige ist. Es kann für Benutzer noch verwirrender werden, wenn das Verhalten viel herumläuft. Wenn wir umkehren, sollten wir es schnell tun, wenn nicht, sollte das aktuelle Verhalten wahrscheinlich für besser oder schlechter stehen.

Ich habe den Begriff "richtig" verwendet, denn bevor pip wheel <localdir> und pip install <localdir> cd <localdir> ; setup.py bdist_wheel in einigen Fällen ein anderes Rad als https://github.com/pypa/pip/issues/7555#issuecomment -595180864 oder #6276 oder einfache Fehler. Ich glaube nicht, dass pip 20.1 so schlechte Räder/Installationen erzeugt, daher glaube ich, dass es in diesem Sinne tatsächlich richtiger ist.

Natürlich wussten wir, dass die Änderung einige Arbeitsabläufe unterbrechen würde, und der Kompromiss muss jetzt, da wir Feedback haben, neu bewertet und rückgängig gemacht oder endgültig bestätigt werden.

Und es kann immer noch andere Räder als setup.py sdist && pip install dist/*.tar.gz .

Mein Vorschlag wäre, den PR rückgängig zu machen und den Fix zu implementieren, indem man zuerst einen sdist durchmischt und dann ein Rad aus dem resultierenden sdist baut.

Dies sollte alle Korrektheitsprobleme lösen, außer in Fällen, in denen das Projekt nicht in der Lage ist, ein sdist korrekt zu erstellen, und das ist IMO kein wichtiger Anwendungsfall, für den es zu lösen ist.

Der Kompromiss dort ist, dass es langsamer sein wird. Sobald wir dies jedoch implementiert haben, können wir die PEP 517-Schnittstelle weiter verfeinern, um optionale APIs hinzuzufügen, die eine Beschleunigung ermöglichen. Das wird wahrscheinlich noch nie so schnell gehen wie diese Änderung, aber wir können dem sicherlich näher kommen.

Diese Änderung macht es praktisch unmöglich, die Genauigkeit weiter zu erhöhen, ohne Leistungsregressionen einzuführen, über die Benutzer wahrscheinlich nicht glücklich sein werden. Wenn wir es jedoch richtig machen und dann mit der Leistung verbessern, können wir einen glücklichen Mittelweg finden, der beide Seiten zufrieden stellt.

Wie das alte Sprichwort sagt, machen Sie es zuerst richtig, dann schnell. Ich fürchte, mit dieser PR haben wir es schnell geschafft und unsere Fähigkeit, es richtig zu machen, ausgesperrt.

Ich stimme immer noch zu, dass die Validierung von sdists wünschenswert ist, jedoch nicht zum Zeitpunkt der Pip-Installation. Vielleicht ist dies eine Funktion für ein zukünftiges sdist-Builder-Tool oder einen Pip-Build-Befehl.

Außerdem erstellt setup.py sdist .egg-info im lokalen Verzeichnis, sodass die gemeldeten Probleme mit schreibgeschützten Quellverzeichnissen oder gleichzeitigen Builds bestehen bleiben.

Wenn dies nicht zur Pip-Installationszeit geschieht, geschieht dies funktional erst zur Pip-Installationszeit einer anderen Person. Das Überspringen bedeutet nur, dass wir mehrere Pfade haben, die ein Projekt von VCS zum installierten Paket fortsetzen kann, und jeder Pfad ist eine weitere Chance für Unterschiede. Dies ist keine neue Sache, im Grunde hat jede Option, die den Installationspfad ändert, selbst bei den anspruchsvollsten Projekten einen anderen Satz von Bytes auf der Festplatte. Es gibt immer subtile Unterschiede, und Sie hoffen nur, dass diese Unterschiede keine Bedeutung haben – oder Sie können alles tun, um diese Unterschiede zu beseitigen, indem Sie es strukturell unmöglich machen, sie von Anfang an zu haben.

Einige Leistungsprobleme könnten tatsächlich wieder auftreten, wenn/beim Erstellen über sdist, aber sie wären wahrscheinlich eine Größenordnung niedriger als das, was wir in pip < 20.1 hatten. Tatsächlich entstand das meiste davon, dass man .git oder ein venv kopierte, oder andere unzusammenhängende umfangreiche Sachen, die nicht im sdist enthalten wären.

Unabhängig davon, womit pip letztendlich enden wird, könnten wir die andere Option wählen, da es unwahrscheinlich ist, dass eine von beiden in der Lage ist, alle zufrieden zu stellen? Ich kann mir vorstellen, dass, wenn der aktuelle Ansatz beibehalten werden soll (ich habe nicht wirklich eine Meinung dazu, was der Standard sein sollte), wir in der Lage sein sollten, einen Fallback für das letzte Ergebnis bereitzustellen, bei dem ein Benutzer wählen kann, einen sdist zu erstellen und zu installieren das Paket von dort.

Außerdem erstellt setup.py sdist .egg-info im lokalen Verzeichnis, sodass die gemeldeten Probleme mit schreibgeschützten Quellverzeichnissen oder gleichzeitigen Builds bestehen bleiben.

Ich denke (zumindest ein kurzer Test stimmt mir zu), dass nur setuptools (nicht distutils ) dies tut, und dieses Verhalten ist konfigurierbar, um das Verzeichnis woanders zu erstellen. Ähnlich wie bei anderen Backends sollten wir ihnen empfehlen können, eine saubere sdist-Generierung durchzuführen.

FWIW, ich glaube nicht, dass wir das sdist-generation --egg-info Verzeichnis in das Arbeitsverzeichnis ablegen müssen, wenn wir den Ansatz von generate-sdist-unpack-it-build-wheel verwenden, da wir es können Legen Sie das in ein temporäres Verzeichnis ab, wie wir es für generate_metadata tun.

@pradyunsg erfordert das keine Änderung der Setuptools? Als ich das letzte Mal den sdist Befehl überprüft habe, hatte ich keine Option zum Angeben des .egg-info Basisstandorts, im Gegensatz zu egg_info das eine --egg-base Option hat, die wir genutzt haben in #7978.

In der Tat! Ich habe in den Setuptools nach der falschen Datei gesucht. 🙈 Ich stehe korrigiert.

Warum ist in diesem Raum alles so komplex? :(

$  ls -la
total 8
drwxr-xr-x  3 dstufft  staff   96 May  6 14:26 .
drwxr-xr-x  9 dstufft  staff  288 Apr 28 15:46 ..
-rw-r--r--  1 dstufft  staff   85 Apr 23 16:23 setup.py

$  py setup.py egg_info --egg-base /tmp/foo sdist
/Users/dstufft/.pyenv/versions/3.8.2/lib/python3.8/site-packages/setuptools/dist.py:471: UserWarning: Normalizing '2020.04.23.3' to '2020.4.23.3'
  warnings.warn(
running egg_info
creating /tmp/foo/dstufft.testpkg.egg-info
writing /tmp/foo/dstufft.testpkg.egg-info/PKG-INFO
writing dependency_links to /tmp/foo/dstufft.testpkg.egg-info/dependency_links.txt
writing top-level names to /tmp/foo/dstufft.testpkg.egg-info/top_level.txt
writing manifest file '/tmp/foo/dstufft.testpkg.egg-info/SOURCES.txt'
reading manifest file '/tmp/foo/dstufft.testpkg.egg-info/SOURCES.txt'
writing manifest file '/tmp/foo/dstufft.testpkg.egg-info/SOURCES.txt'
running sdist
warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md

running check
warning: Check: missing required meta-data: url

warning: Check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) must be supplied

creating dstufft.testpkg-2020.4.23.3
copying files to dstufft.testpkg-2020.4.23.3...
copying setup.py -> dstufft.testpkg-2020.4.23.3
Writing dstufft.testpkg-2020.4.23.3/setup.cfg
creating dist
Creating tar archive
removing 'dstufft.testpkg-2020.4.23.3' (and everything under it)

$ ls -la                                        
total 8
drwxr-xr-x  4 dstufft  staff  128 May  6 14:28 .
drwxr-xr-x  9 dstufft  staff  288 Apr 28 15:46 ..
drwxr-xr-x  3 dstufft  staff   96 May  6 14:28 dist
-rw-r--r--  1 dstufft  staff   85 Apr 23 16:23 setup.py

https://github.com/pypa/pip/issues/8165#issuecomment -624669107 das fühlt sich an wie eine hübsche Show, die den Fehler stoppt, wohl nicht unser Fehler, aber es ist eine Art von Fehlern, die meiner Meinung nach während der PEP 517-Diskussion auftreten würden, wenn Das Ausführen von In-Place-Builds wurde standardmäßig angezeigt.

bdist_wheel wurde in der Vergangenheit gebeten, sein Build-Verzeichnis automatisch zu bereinigen. Diese Funktion sollte eingebaut werden. Sind die anderen distutils-Builds sauber?

Wenn es sich um SCons handelte, würde es sich an die Dateien erinnern, die ihm wichtig waren, und zusätzliche Dateien im build/-Verzeichnis vom Rad weglassen, selbst wenn sie im Dateisystem vorhanden waren.

Ich glaube, das obige Problem betrifft nicht nur Manylinux. Dies sollte immer dann passieren, wenn das Build-Verzeichnis nicht spezifisch genug ist, um das ABI zu erfassen (im Fall von setuptools scheint es, dass nur die Plattform und die Python-Version im ABI-Tag im Build-Verzeichnis erfasst werden). Ich denke, dies geht auch mit dem aktuellen Interpreter über ABI hinaus. Wenn zum Beispiel etwas gegen NumPy verlinkt, denke ich, dass es ein ABI hat, das auf neueren, aber nicht auf älteren NumPy funktioniert, und es sei denn, sie codieren dies in der Benennung des Build-Verzeichnisses, dann wird dies Effekt verwendet auch so.

Das automatische Bereinigen des Build-Verzeichnisses löst das Problem nicht, es macht es nur weniger wahrscheinlich (zum Beispiel könnte das parallele Ausführen von zwei pip wheel Aufrufen immer noch das Problem auslösen), obendrein einer der vermeintlichen Gründe für die Implementierung Auf diese Weise (zumindest während der PEP 517-Diskussion) würde dies mehr Leistung bieten, indem das Caching zwischen Aufrufen für inkrementelle Builds ermöglicht wird. IOW das aktuelle Verhalten ist das, was eine Teilmenge wollte, die Wiederverwendung von Build-Artefakten zwischen den Durchläufen Paketanpassung).

Mit genügend Flags für den zugrunde liegenden setuptools Befehl können Sie dies natürlich beheben (etwas wie py setup.py egg_info --egg-base /tmp/foo build --build-base /tmp/foo/build-base bdist_wheel --bdist-dir /tmp/foo/bdist würde es tun).

Ich möchte jedoch wiederholen, dass das Problem nicht an zusätzlichen Dateien liegt, sondern daran, dass die erwartete ABI, mit der das Rad kompatibel war, geändert wurde und die .so nicht neu erstellt wurden. Wenn SCons schlau genug ist, um zu wissen, dass Python, das mit pymalloc erstellt wurde, ein Build-Verzeichnis benötigt und Python mit einem anderen erstellt wird (einschließlich Dinge wie NumPy-Versionen, auf die .so möglicherweise verlinkt), dann ist es nicht betroffen. Wenn es ein zuvor erstelltes Artefakt mit einer anderen ABI wiederverwenden würde, ist es betroffen.

Ich habe versucht, Enscons zu testen, aber ich konnte rsalette nicht ohne Fehler erstellen.

Ich habe versucht , zu Test scikit-build zu sehen , wie es behandelt inkrementelle baut, und egal , was ich tat es sich auf der 2. Build gekotzt Jut und ich musste manuell löschen _skbuild Verzeichnis jedes Mal , um es an fehlerfrei laufen.

Cool. Entschuldigung, dass Enscons aktualisiert wurde und rsalette nicht.

Am Mittwoch, 6. Mai 2020, um 16:18 Uhr schrieb Donald Stufft:

Ich habe versucht, Enscons zu testen, aber ich konnte rsalette nicht ohne Fehler erstellen.

Ich habe versucht , zu Test scikit-build zu sehen , wie es behandelt inkrementelle baut, und egal , was ich tat es sich auf der 2. Build gekotzt Jut und ich musste manuell löschen _skbuild Verzeichnis jedes Mal , um es an fehlerfrei laufen.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub https://github.com/pypa/pip/issues/7555#issuecomment-624867490 an oder melden Sie sich ab https://github.com/notifications/unsubscribe-auth/AABSZERIEDAPUIXCPAKBBUDRQHAXRANCNFSM4KCV5MHQ .

Entschuldigung, dass Enscons aktualisiert wurde und rsalette nicht.

Gibt es eine gute C ext, die enscons verwendet, die aktualisiert wird? Ich habe mich nur für Rsalette entschieden, weil es an erster Stelle in der Liste stand und keine Lust hatte, es zu debuggen, und ich bin glücklich, es mit etwas anderem zu versuchen.

Das einzige Problem mit rsalette ist, dass ROOT_IS_PURELIB an Environment in SConstruct übergeben werden sollte. Es hat keine C-Erweiterung. cryptacular sieht gut aus.

#8165 (Kommentar)

Damit bin ich, denke ich, einverstanden, dass wir diese Änderung rückgängig machen sollten.

Ich denke, die neuen Probleme sind viel größer als erwartet. Vielleicht ein kurzes 20.1.1 zum Zurücksetzen und dann können wir eine längere Diskussion darüber führen, wie sowohl die Probleme von In-Tree- als auch Out-of-Tree-Builds gelöst werden können?

Ich stimme auch für zurück und verfolge https://discuss.python.org/t/proposal-adding-a-persistent-cache-directory-to-pep-517-hooks/2303/15 als Lösung dafür (das würde zulassen, dass Back-Ends nicht direkt erstellt werden, sodass solche Probleme nicht offengelegt werden). Melden Sie sich auch in diesem Thread an, wenn Sie dem Vorschlag dort zustimmen.

Das erscheint mir auch sinnvoll. Ich denke, dass ein In-Tree- (oder Build-from-sdist)-Ansatz einige äußerst bedeutende Vorteile hat (ich bin mir ziemlich sicher, dass wir von einem Teil der Benutzerbasis Klageschreie bekommen werden, wenn wir zurückkehren 🙂), aber die Nachteile sind es auch wesentlich.

Mir ist nicht klar, wie die Benutzeroberfläche hier sein sollte (Standard: Welcher Ansatz? Welche Optionen sollten wir haben?), aber ich denke, wir sollten uns etwas mehr Zeit nehmen, um das zu entscheiden, anstatt Entscheidungen zu treffen, während wir die aktuellen Probleme bekämpfen .

In Ordnung! Ich denke, der allgemeine Konsens besteht darin, umzukehren und neu zu bewerten. Ich werde eine PR dafür einreichen. :)

Melden Sie sich auch in diesem Thread an, wenn Sie dem Vorschlag dort zustimmen.

Bitte tun Sie es - ich habe Kommentare abgegeben, aber ich bin an einem Punkt angelangt, an dem ich nicht genug weiß, um sinnvolle Vorschläge zu machen, daher wäre der Input von Leuten mit mehr Erfahrung wertvoll.

Habe gerade ein paar Big-Blobs-of-Text in https://github.com/pypa/pip/issues/8165#issuecomment -625401463 abgelegt. Ich gehe jetzt für heute weg... Am Ende war ich etwas frustriert, als ich die persönlichen Notizen schrieb. Auf #5599 zu landen und negative Benutzerkommentare zu lesen, hat sicherlich nicht geholfen.

Hallo Leute, ich habe mir noch einige Gedanken gemacht, hier ist mein aktueller Standpunkt zu diesem Thema.

  1. Bauen Sie ein sdist an Ort und Stelle, entpacken Sie das sdist an einem temporären Ort und bauen Sie dann daraus.

Ich glaube immer noch, dass Pip Install / Pip Wheel nicht der richtige Ort ist, um schlechte Sdists zu fangen. Sollte das nicht eine Backend-Verantwortung sein, um überhaupt keine schlechten Sdists zu erstellen? Außerdem würde ich denken, dass der bedingungslose Build über sdist wahrscheinlich genauso störend ist wie der Build an Ort und Stelle.

  1. Fügen Sie eine Pip-Option hinzu, um an Ort und Stelle zu bauen.

Das gefällt mir kurzfristig am besten, da Lösung 4 es nicht geschafft hat. Ist es verfrüht, das in Pip 20.1.1 hinzuzufügen?

  1. Aktualisieren Sie PEP 517 mit einer Art Mechanismus, damit Back-Ends mit Front-Ends kommunizieren können, wenn sie für In-Place-Builds "sicher" sind.

Mit diesem Pip müsste man immer noch auf seinen kaputten und nicht reparierbaren Copytree zurückgreifen, also bin ich nicht für diesen.

  1. Ändern Sie Pip, um immer an Ort und Stelle zu bauen.

Dieser wird also als zu störend erachtet und wir werden in 20.1.1 zurückkehren.

  1. Ändern Sie pip so, dass es standardmäßig an Ort und Stelle erstellt wird, mit einer Option zum Erstellen außerhalb des Baums.

Das könnte das langfristige Ziel sein, die Option, Out-of-Tree-Blending mit dem Cache-Verzeichnis-Konzept aufzubauen?

Ich mag CLI-Optionen wirklich nicht, besonders solche wie diese. Was passiert, wenn ich zwei Pakete aufliste, die sich auf meinem lokalen FS befinden, und ich eines an Ort und Stelle erstellen muss und eines nicht? Wenn wir eine Option für das eine oder andere anbieten, werden am Ende vorhandene Pakete entstehen, die nur mit dem einen oder anderen erstellt werden können.

Es riecht für mich auch nach einer Option, die nur deshalb existiert, weil ein Projekt keine Entscheidung treffen konnte und diese Entscheidung einfach an den Endbenutzer weitergegeben wurde.

Beim Bauen über sdist geht es nicht gerade darum, schlechte sdists zu fangen. Im Wesentlichen geht es darum, die möglichen Variationen des "Pfads" zu reduzieren, die ein Projekt durchlaufen kann, bevor es installiert wird. Das Hinzufügen eines Flags in gewisser Weise macht dieses Problem schlimmer und nicht besser.

Für das, was ich meine, haben wir ein paar "Pfade", die Installationen durchlaufen können:

  1. VCS -> Sdist -> Rad -> Installiert
  2. VCS -> Rad -> Installiert
  3. VCS -> Installiert (alt)

Es gibt einige zusätzliche Pfade, die auslaufen, aber im Allgemeinen sind dies unsere 3 (und idealerweise wird auch 3 auslaufen). Es gibt auch bearbeitbare Installationen, die jedoch nicht so schnell verschwinden.

Wir können uns vorstellen, dass entweder ein sdist oder ein Rad auf PyPI hochgeladen und von dort installiert wird, bis es Teil desselben "Pfads" ist, Sie pausieren es einfach und beenden es auf einem anderen Computer.

Das Problem bei der Verwendung mehrerer solcher "Pfade" besteht darin, dass es Inkonsistenzen in der endgültigen resultierenden Installation gibt. Sie passieren nicht immer, aber es ist ein leicht zu beobachtender Fall, dass es häufig vorkommt. Oft sind diese Inkonsistenzen keine große Sache, aber manchmal sind sie es.

Wenn wir solche In-Place-Builds machen, dann sagen wir im Grunde, dass wir nie in der Lage sein werden, auf einen einzigen Pfad zusammenzubrechen, und wir müssen uns einfach immer mit diesem seltsamen Randfall auseinandersetzen, in dem manchmal Benutzer erhalten unterschiedliche Ergebnisse, je nachdem, wie die Installation durchgeführt wurde.

Als zusätzlicher Vorteil kann dies auch als Zwangsfunktion dienen, um sicherzustellen, dass der glückliche Weg glücklich bleibt.

Meistens stimme ich @dstufft zu , und insbesondere stimme ich zu, dass der Build-from-sdist-Ansatz nicht als "Versuch, sdists zu validieren" angesehen werden sollte, sondern als "alles folgt dem "Quellbaum -> sdist -> Rad -> Route installieren". (nur einige Dinge überspringen einige anfängliche Schritte)".

Einen Punkt möchte ich jedoch ansprechen:

Was passiert, wenn ich zwei Pakete aufliste, die sich auf meinem lokalen FS befinden, und ich eines an Ort und Stelle erstellen muss und eines nicht?

Führen Sie einfach die beiden Pakete in zwei separaten Pip-Läufen mit unterschiedlichen Optionen aus?!? Ich weiß , es ist möglich , eine eine Abhängigkeit des anderen ist und Ihr Punkt im Allgemeinen hält, aber es scheint eine allgemeine Neigung zu sein für die Menschen davon ausgehen , dass jedes installieren Szenario in einem einzigen Durchlauf von pip kollabiert werden muss, und ich don‘ Ich denke nicht, dass es vernünftig ist (wir hatten vollkommen gute Problemumgehungen für Probleme, die vom Benutzer abgelehnt wurden, weil "das bedeutet, dass ich meine Anforderungsliste in zwei Teile aufteilen müsste")

Beachten Sie, dass wir beim Zurücksetzen Probleme wie #6276, die aufgrund der Implementierung von In-Tree-Builds geschlossen wurden, erneut öffnen müssen.

Ein Teil des Problems ist, dass pip beim Auflösen von Abhängigkeiten nicht berücksichtigt, was bereits installiert ist (ich bin mir nicht sicher, ob die neue Resolver-Funktion das ändert?). Sie müssen also alles in einem einzigen pip-Aufruf enthalten, wenn Sie es auflösen möchten Abhängigkeiten "richtig" (sofern unser aktueller Resolver alles richtig macht).

Wenn der neue Resolver berücksichtigt, was bereits installiert ist, wären pip install foo bar und pip install foo && pip install bar ungefähr gleich und völlig egal, aber wenn nicht (und dasselbe gilt jetzt ungefähr) Wenn beide Projekte von "Spam" abhängen, aber foo erforderlich < 2 und bar erforderlich > 1 sind, erhalten wir eine ungültige Installation.

Das ist aber eine Tangente :)

(Ich bin mir nicht sicher, ob die neue Resolver-Arbeit das ändert?)

Eingaben willkommen auf #7744. :)

  1. Ändern Sie Pip, um immer an Ort und Stelle zu bauen.

Dieser wird also als zu störend erachtet und wir werden in 20.1.1 zurückkehren.

Um es klar zu sagen, wir haben es auch "zu schnell eingeführt" und der von uns gewählte Rollout-Ansatz ist definitiv ein Grund dafür, dass dies zu störend war.

  1. Fügen Sie eine Pip-Option hinzu, um an Ort und Stelle zu bauen.

@dstufft @pfmoore Ich sehe diese Art von Option als Opt-In-Mechanismus, damit wir Benutzer schrittweise zu In-Place-Builds https://github.com/pypa/pip/issues/8165#issuecomment -625501216

Ich werde eine PR dafür einreichen. :)

8221 ist es.

20.1.1 wurde veröffentlicht und enthält die rückgängig gemachten Änderungen.

Wenn wir in Fedora Python-RPM-Pakete erstellen, sind wir Dinosaurier und der Standardweg ist die Verwendung von python setup.py build . Mit PEP 517 haben wir stattdessen eine "vorläufige" Möglichkeit hinzugefügt, pip wheel verwenden. Bei Erweiterungsmodulen haben wir jedoch ein Problem mit dem Ansatz "Quellen nach tmp verschieben, von dort erstellen", den pip verwendet, um sie zu erstellen.

Unsere Build-Maschinerie fügt einige Compiler-Flags ein, sodass die Build-Artefakte (in diesem Fall .so Erweiterungsmodule) Metadaten über ihre Quellen enthalten. Später gibt es ein Shell-Skript, das die Build-Artefakte durchläuft, diese Informationen extrahiert und die Quellen nach /usr/src/debug kopiert, um sie über ein spezielles *-debugsource RPM zu installieren. Die Maschine erwartet, dass alles innerhalb des Arbeitsbaums gebaut wird und es funktioniert nicht wirklich gut, wenn es draußen gebaut wird. Hier sind die Dinge, die (gemeinsam) getan werden können, um das Problem auf unserer Seite zu mildern:

1. set the `$TMPDIR` environment variable to have it within the place where the RPM script expects it (i.e. `export TMPDIR=%{_builddir}/.tmp` (and create it))

2. use `pip wheel` with the `--no-clean` option to keep the copied sources in `$TMPDIR`

3. run some shell kung fu to rewrite the "what is my source" information to the correct location: `find %{buildroot} -iname '*.so' -print0 | xargs --no-run-if-empty -0 -n1 /usr/lib/rpm/debugedit -b "%{_builddir}/.tmp/pip-req-build-"* -d "$PWD"`

4. (Optional: clean `$TMPDIR` manually.)

Dies ist effektiv der Weg, den ich eingeschlagen habe, als ich die Pip-Integration, #6505 usw.

Iterative Builds mit pip werden heute effektiv gebrochen, was ein großer Verlust für Gruppen ist, die eine große Menge an Python-Code in C-Erweiterungsform haben, daher habe ich den Build mit setup.py .

pip benötigt einen build Befehl und das Endergebnis des build Befehls sollte an andere Unterbefehle weitergegeben werden können, wie wheel , install , etc.

Im Moment behandelt pip install pip effektiv als build und install , was einige Leute _nicht_ wollen, die binäre Artefakte erstellen und zwischenspeichern und Binärdateien über Lesen installieren - nur Halterungen usw.

Ich wünschte wirklich, es gäbe eine Möglichkeit, setup.py zu verwenden, um die Binärdateien zu erstellen, und dann pip install sie zu erstellen, ohne ein bdist erstellen zu müssen, aber das scheint heute nicht möglich zu sein , da pip und distutils / setuptools nicht übereinstimmen, wo die binären Artefakte zu finden sind.

Ich wünschte wirklich, es gäbe eine Möglichkeit, setup.py zu verwenden, um die Binärdateien zu erstellen, und dann mit pip zu installieren, ohne einen bdist zu erstellen, aber das scheint heute nicht möglich zu sein, da pip und distutils/setuptools nicht übereinstimmen wo die binären Artefakte zu finden sind.

Ich bin mir nicht sicher, ob ich dem folge - Sie sagen, dass Sie eine Möglichkeit zur Verwendung von Binärdateien wünschen, aber nicht die bereits vorhandenen binären Distributionsformate verwenden möchten. Warum ist das so?

Ich wünschte wirklich, es gäbe eine Möglichkeit, setup.py zu verwenden, um die Binärdateien zu erstellen, und dann mit pip zu installieren, ohne einen bdist zu erstellen, aber das scheint heute nicht möglich zu sein, da pip und distutils/setuptools nicht übereinstimmen wo die binären Artefakte zu finden sind.

Ich bin mir nicht sicher, ob ich dem folge - Sie sagen, dass Sie eine Möglichkeit zur Verwendung von Binärdateien wünschen, aber nicht die bereits vorhandenen binären Distributionsformate verwenden möchten. Warum ist das so?

Die bdist-Formate sind extrem einschränkend. Meine Gruppe muss auf ein dummes Format wie tar zurückgreifen und es dann wörtlich entpacken (keine der BSDs werden unterstützt, Debian wird nicht unterstützt usw.).

Was ich letzte Nacht entdeckt habe, ist, dass die Verwendung eines dummen bdist nicht über pip installiert werden kann. Den dummen Binärdateien fehlen die Metadaten, die erforderlich sind, um über pip , AFAICT installiert zu werden, wo ich denke, dass Pip Wheels ins Spiel kommen.

Ich habe es auch mit egg und zip versucht, aber ihnen fehlen die Metadaten, die für die Installation mit nur einem file:// URI erforderlich sind.

Ich habe mich damit beschäftigt, das Bauen über Distutils und Setuptools mit make in ein größeres Build-System zu integrieren, daher kann ich nicht sagen, ob ich "alle richtigen Dinge" getan habe, damit die Dinge so funktionieren wie ein Standard- bdist Anruf hätte.

Von https://github.com/pypa/pip/issues/2195#issuecomment -664728481 kann ich sagen, dass ich mehr als glücklich bin, #7882 hinter --use-feature=in-tree-build zu wiederholen.

Hurra! Klingt wie ein Plan!

Lassen Sie uns dieses Mal auch den Docstring von --build aktualisieren. ;)

Ausgehend von #2195 (Kommentar) kann ich sagen, dass ich mehr als glücklich bin, #7882 hinter --use-feature=in-tree-build zu wiederholen.

Neugierig, ob es sinnvoll wäre, eine Option in-tree-build in pyproject.toml setzen, ebenso wie über die Befehlszeile? Dies wäre ziemlich gut, um #6276 aufzulösen, ohne ein Bash-Skript oder Makefile erstellen zu müssen, um Pip zu umhüllen. (Nicht, dass das ein besonders großes Problem wäre.)

eine In-Tree-Build-Option in pyproject.toml festlegen

@davidhewitt Dies ist mehr oder weniger Option 3 in der ursprünglichen Beschreibung dieses Problems. Nach meinem Verständnis ist der derzeitige Konsens, dass es besser ist, eine zusätzliche Option zu vermeiden, wenn wir können. Daher die Idee, In-Tree-Builds mit --use-feature während einer Übergangszeit zu aktivieren, mit dem längerfristigen Ziel, es zum Standard- und einzigen Mechanismus zu machen.

Übrigens, ich werde dies nicht rechtzeitig zum 20.3 implementieren können, aber ich habe es immer noch vor, es hoffentlich in 20.4 zu tun.

@sbidoul Ich habe einen Patch geschrieben, um diese Funktion zu erhalten - siehe # 9091.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen