<p>pip 19.0 kann keine Pakete installieren, die das zu installierende Paket aus CWD importieren</p>

Erstellt am 23. Jan. 2019  ·  89Kommentare  ·  Quelle: pypa/pip

Umgebung

  • Pip-Version: 19.0
  • Python-Version: 3.6
  • Betriebssystem: MacOS

Beschreibung
Beim Ausführen von pip install pyinstaller == 3.4 mit pip 19.0 wird ein Installationsfehler angezeigt. ModuleNotFoundError: Kein Modul mit dem Namen 'PyInstaller'

Erwartetes Verhalten
Erwarten Sie, dass pyinstall installiert wird, wie es bei pip 18.1 der Fall ist

Wie zu reproduzieren
Verwenden von Python3:
pip install pyinstaller = 3.4

Ausgabe

pip install pyinstaller==3.4
Collecting pip
  Using cached https://files.pythonhosted.org/packages/60/64/73b729587b6b0d13e690a7c3acd2231ee561e8dd28a58ae1b0409a5a2b20/pip-19.0-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 9.0.3
    Uninstalling pip-9.0.3:
      Successfully uninstalled pip-9.0.3
Successfully installed pip-19.0
(BuildVEnv) jlaroche-mbp:TrackSense$ pip install pyinstaller
Collecting pyinstaller
  Using cached https://files.pythonhosted.org/packages/03/32/0e0de593f129bf1d1e77eed562496d154ef4460fd5cecfd78612ef39a0cc/PyInstaller-3.4.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  Complete output from command /Users/jlaroche/Dev/uapkg/packages/system/algo/BuildVEnv/bin/python3 /Users/jlaroche/Dev/uapkg/packages/system/algo/BuildVEnv/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /var/folders/j6/7t8sg1vj4q97zhh9z5cdmxbm4rz935/T/tmps3z6flnv:
  Traceback (most recent call last):
    File "/Users/jlaroche/Dev/uapkg/packages/system/algo/BuildVEnv/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 207, in <module>
      main()
    File "/Users/jlaroche/Dev/uapkg/packages/system/algo/BuildVEnv/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 197, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/Users/jlaroche/Dev/uapkg/packages/system/algo/BuildVEnv/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 54, in get_requires_for_build_wheel
      return hook(config_settings)
    File "/private/var/folders/j6/7t8sg1vj4q97zhh9z5cdmxbm4rz935/T/pip-build-env-lo_ir5_f/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 115, in get_requires_for_build_wheel
      return _get_build_requires(config_settings, requirements=['wheel'])
    File "/private/var/folders/j6/7t8sg1vj4q97zhh9z5cdmxbm4rz935/T/pip-build-env-lo_ir5_f/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 101, in _get_build_requires
      _run_setup()
    File "/private/var/folders/j6/7t8sg1vj4q97zhh9z5cdmxbm4rz935/T/pip-build-env-lo_ir5_f/overlay/lib/python3.6/site-packages/setuptools/build_meta.py", line 85, in _run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 20, in <module>
      from PyInstaller import __version__ as version, HOMEPATH, PLATFORM
  ModuleNotFoundError: No module named 'PyInstaller'

Hinweis zum Betreuer auf der Zeitachse: Siehe https://github.com/pypa/pip/issues/6163#issuecomment -460563963

PEP 517 impact auto-locked bug

Hilfreichster Kommentar

[...] könnte jemand bitte überprüfen, ob --no-use-pep517 dies für ihn behebt?

PyInstaller lässt sich problemlos mit --no-use-pep517 installieren.

Alle 89 Kommentare

Dies scheint ein Problem zu sein, wenn es darum geht, wie sich pyinstaller selbst zur Installation importiert.

Es könnte eine gute Idee sein, ein Problem bei den PyInstaller-Leuten einzureichen.

Wir verwenden derzeit 18.1, und ein Upgrade auf 19.0 verursacht dieses Problem auch für uns. Es gibt ein verwandtes Problem im PyInstaller-Repo, bei dem pip '' nicht in sys.path enthalten ist.

https://github.com/pyinstaller/pyinstaller/issues/2730

Ich denke, das ist ein ziemlich häufiger Workflow. Sie geben __version__ = "1.2.3" in foo/__init__.py und machen dann import foo in setup.py damit Sie die Version nicht an zwei Stellen angeben müssen. Und jeder Benutzer der Bibliothek kann die Version gemäß PEP 396 überprüfen.

# foo/__init__.py
__version__ = "1.2.3"
# setup.py
from setuptools import setup

import foo

setup(..., version=foo.__version__)

Dies geschieht auch nur, wenn Sie eine pyproject.toml -Datei (und setup.py ) haben. Entfernen Sie es und die Installation funktioniert einwandfrei. Es scheint also einige Unterschiede im Verhalten zu geben. Vielleicht ändert die traditionelle Methode sys.path / PYTHONPATH ?

Ah, ich glaube ich verstehe was passiert. Da Sie mit einer pyproject.toml -Datei Pip mitteilen, dass Sie PEP 517/518 verwenden möchten.

# pyproject.toml
[build-system]
requires = ["setuptools", "wheel"]

Das Obige sagt Pip, dass es setuptools und wheel braucht, um PyInstaller zu erstellen. Aber im Fall von PyInstaller hat es dies auch in seinen setup.py :

# setup.py
from PyInstaller import __version__

Aus Sicht von PEP 517 bedeutet dies, abgesehen von setuptools und wheel , dass es sich selbst bauen muss. Welches ist natürlich ein bisschen komisch.

# pyproject.toml
[build-system]
requires = ["setuptools", "wheel", "PyInstaller"]

Wie @cjerdonek in https://github.com/pypa/pip/issues/6175#issuecomment -456769285 erwähnt, könnte jemand bitte überprüfen, ob --no-use-pep517 dies für ihn behebt?

Ich vermute, die Ursache für dieses Problem ist, dass die Build-Isolation oder der PEP 517-Code nicht sicherstellt, dass sich das Stammverzeichnis des Paketverzeichnisses im sys.path befindet, da bei pandas eine versioneer.py neben setup.py steht. Ich erinnere mich, dass dies irgendwann auftauchte, aber ich erinnere mich nicht genau, was diese Diskussion war. Dies kann als Problem mit dem Setuptools-Build-Backend anstelle von pip angesehen werden, oder es liegt möglicherweise am Fehler des Isolationsmechanismus von pip.

[...] könnte jemand bitte überprüfen, ob --no-use-pep517 dies für ihn behebt?

PyInstaller lässt sich problemlos mit --no-use-pep517 installieren.

Ok, dann ist das sicherlich ein Problem mit dem neuen PEP 517-Code und ich bin mir ziemlich sicher, dass das Verzeichnis, das den Projektstamm enthält, nicht zu sys.path hinzugefügt wurde. Vielleicht hat @pfmoore ein besseres Gefühl dafür, ob dies die Verantwortung von pip oder setuptools sein sollte.

Wenn es einem anderen Beispiel hilft (über apache-airflow ist pip install pendulum==1.4.4 schlägt fehl, aber pip install --no-use-pep517 pendulum==1.4.4 funktioniert.

Die Stapelverfolgung, die wir erhalten, ist ähnlich:

Collecting pendulum==1.4.4
  Using cached https://files.pythonhosted.org/packages/85/a5/9fc15751f9725923b170ad37d6c61031fc9e941bafd5288ca6ee51233284/pendulum-1.4.4.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  Complete output from command /Users/ash/.virtualenvs/clean-airflow/bin/python3.7 /Users/ash/.virtualenvs/clean-airflow/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /var/folders/lr/9jc9vkgn025fn6jmwm4mv4_w0000gn/T/tmprosed3kj:
  Traceback (most recent call last):
    File "/Users/ash/.virtualenvs/clean-airflow/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py", line 207, in <module>
      main()
    File "/Users/ash/.virtualenvs/clean-airflow/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py", line 197, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/Users/ash/.virtualenvs/clean-airflow/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py", line 54, in get_requires_for_build_wheel
      return hook(config_settings)
    File "/private/var/folders/lr/9jc9vkgn025fn6jmwm4mv4_w0000gn/T/pip-build-env-g__m0jh6/overlay/lib/python3.7/site-packages/setuptools/build_meta.py", line 115, in get_requires_for_build_wheel
      return _get_build_requires(config_settings, requirements=['wheel'])
    File "/private/var/folders/lr/9jc9vkgn025fn6jmwm4mv4_w0000gn/T/pip-build-env-g__m0jh6/overlay/lib/python3.7/site-packages/setuptools/build_meta.py", line 101, in _get_build_requires
      _run_setup()
    File "/private/var/folders/lr/9jc9vkgn025fn6jmwm4mv4_w0000gn/T/pip-build-env-g__m0jh6/overlay/lib/python3.7/site-packages/setuptools/build_meta.py", line 85, in _run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 47, in <module>
      from build import *
    File "/Users/ash/.virtualenvs/clean-airflow/lib/python3.7/site-packages/pip/_vendor/pep517/build.py", line 7, in <module>
      from pip._vendor import pytoml
  ModuleNotFoundError: No module named 'pip'

Auch die Installation von Folgendem funktioniert nicht mit pip v 19.0, würde aber bei Verwendung von --no-use-pep5517 funktionieren:
Pendel == 1.5.0 (AttributeError: Modul 'enum' hat kein Attribut 'IntFlag')
Pendel == 1.5.1 (AttributeError: Modul 'enum' hat kein Attribut 'IntFlag')
Pendel == 2.0.0 (AttributeError: Modul 'enum' hat kein Attribut 'IntFlag')
Pendel == 2.0.1 (AttributeError: Modul 'enum' hat kein Attribut 'IntFlag')
Pendel == 2.0.2 (AttributeError: Modul 'enum' hat kein Attribut 'IntFlag')

Während 2.0.3 und 2.0.4 gut installieren.

cartopy (zumindest die neueste Version) kann seit 19.0 nicht mehr installiert werden und die versioneer.py neben setup.py kann nicht importiert werden

Dies ist auch ein Problem bei einigen Projekten, mit denen ich mich befasse. Wir verwenden eine pyproject.toml, um unsere Python Black-Parameter zu definieren, und führen in unserer setup.py ein ähnliches from project.version import __version__ aus.

Zumindest habe ich das Gefühl, dass es ausreichen würde, keine Projektisolation in der pyproject.toml zu definieren. Es erscheint mir unvernünftig, jemanden, der das Projekt installieren möchte, dazu zu bringen, --no-buid-isolation oder --no-use-pep517

Der Fehler scheint in get_requires_for_build_wheel , und das Setuptools-Backend führt setup.py , um eine Art Selbstbeobachtung durchzuführen, um die Build-Anforderungen zu bestimmen (der spezifische Code ist hier ). Dieser Code erscheint mir seltsam und ich verstehe nicht, warum er erforderlich ist. Mein anfänglicher Instinkt ist, dass dies ein Fehler im Setuptools-Backend ist, der von ihnen behoben werden sollte.

PEP 517 gibt nicht an, dass Frontends Hooks in einer Umgebung ausführen sollen, in der das Build-Verzeichnis zu sys.path , und es besteht die Möglichkeit, dass die Isolation dadurch unterbrochen wird (wenn das Build-Verzeichnis eine Kopie von enthält einige erforderliche, aber nicht spezifizierte Pakete, zum Beispiel). So ist meine Präferenz wäre, nicht das Build - Verzeichnis hinzuzufügen sys.path . Dies kann jedoch sinnvoll sein, wenn dies eine schnelle Lösung für diese Regression bietet. Ich denke jedoch nicht, dass Projekte darauf beruhen sollten.

Zusammenfassung:

  1. Dies sollte setuptools zur Überprüfung als Backend-Problem gemeldet werden. Ich würde es als ideale Lösung in Betracht ziehen, es im Setuptools-Backend zu reparieren (möglicherweise nur, indem sie das Build-Verzeichnis zu sys.path hinzufügen).
  2. Wenn setuptools dies nicht tut, könnte pip das Build-Verzeichnis zu sys.path hinzufügen, aber ich glaube nicht, dass PEP 517 dies als Verantwortung des Frontends ansieht.
  3. Wenn das Build-Verzeichnis für Hooks von sys.path sichtbar sein muss, ist mindestens eine PEP-Klärung erforderlich.

Ich glaube nicht, dass dieses Szenario bei der Entwicklung von PEP 517 berücksichtigt wurde. Vielleicht, weil es setuptools-spezifisch ist (oder eher spezifisch für Backends, die beliebigen Python-Code als Teil des Builds ausführen).

Ich denke, es ist ziemlich üblich, dass Leute etwas aus dem aktuellen Verzeichnis in ein setup.py importieren und die Dinge im Allgemeinen so behandeln, als ob setup.py in $PWD .

Ich denke, es ist vernünftig, diese Verantwortung auf setuptools , da dies wahrscheinlich das einzige Projekt ist, das es wirklich braucht.

Ja, wenn ich noch etwas darüber nachdenke, bin ich mir sicher, dass es eine Backend-Verantwortung für Setuptools ist. Vor PEP 517 führte pip setup.py als Skript aus, sodass Standard-Python-Regeln das Skriptverzeichnis auf sys.path . Unter PEP 517 wird der Aufruf von setup.py durch Aufrufe der Backend-Hooks ersetzt, sodass diese Hooks die Semantik beibehalten müssen. Da setuptools setup.py in Bearbeitung von den Hooks aus ausführt, muss es sys.path selbst verwalten. Hoffentlich ist es keine große Lösung für sie. @jeanlaroche (oder jemand anderes, der dieses Problem hat) Könnten Sie ein Problem im Setuptools-Tracker ansprechen und auf diesen Thread zurückgreifen?

[...] könnte jemand bitte überprüfen, ob --no-use-pep517 dies für ihn behebt?

Ich kann bestätigen, dass --no-use-pep517 den Erfolg von pip install pandas ermöglicht.

Ich kann auch bestätigen, dass die Verwendung von --no-use-pep517 für alle meine kaputten Pakete funktioniert

Erfolg auch für mich

pip install pyinstaller --no-use-pep517
Collecting pyinstaller
  Using cached https://files.pythonhosted.org/packages/03/32/0e0de593f129bf1d1e77eed562496d154ef4460fd5cecfd78612ef39a0cc/PyInstaller-3.4.tar.gz
Requirement already satisfied: setuptools in c:\python37\lib\site-packages (from pyinstaller) (39.0.1)
Collecting pefile>=2017.8.1 (from pyinstaller)
  Downloading https://files.pythonhosted.org/packages/ed/cc/157f20038a80b6a9988abc06c11a4959be8305a0d33b6d21a134127092d4/pefile-2018.8.8.tar.gz (62kB)
    100% |████████████████████████████████| 71kB 1.0MB/s
Collecting macholib>=1.8 (from pyinstaller)
  Downloading https://files.pythonhosted.org/packages/41/f1/6d23e1c79d68e41eb592338d90a33af813f98f2b04458aaf0b86908da2d8/macholib-1.11-py2.py3-none-any.whl
Collecting altgraph (from pyinstaller)
  Downloading https://files.pythonhosted.org/packages/0a/cc/646187eac4b797069e2e6b736f14cdef85dbe405c9bfc7803ef36e4f62ef/altgraph-0.16.1-py2.py3-none-any.whl
Collecting pywin32-ctypes (from pyinstaller)
  Using cached https://files.pythonhosted.org/packages/9e/4b/3ab2720f1fa4b4bc924ef1932b842edf10007e4547ea8157b0b9fc78599a/pywin32_ctypes-0.2.0-py2.py3-none-any.whl
Collecting future (from pefile>=2017.8.1->pyinstaller)
  Downloading https://files.pythonhosted.org/packages/90/52/e20466b85000a181e1e144fd8305caf2cf475e2f9674e797b222f8105f5f/future-0.17.1.tar.gz (829kB)
    100% |████████████████████████████████| 829kB 1.6MB/s
Installing collected packages: future, pefile, altgraph, macholib, pywin32-ctypes, pyinstaller
  Running setup.py install for future ... done
  Running setup.py install for pefile ... done
  Running setup.py install for pyinstaller ... done
Successfully installed altgraph-0.16.1 future-0.17.1 macholib-1.11 pefile-2018.8.8 pyinstaller-3.4 pywin32-ctypes-0.2.0

Ich denke nicht, dass dies ein Fehler in pip / setuptools ist. Nach meiner Lektüre des Abschnitts "Build Environment" von pyproject.toml deklarierten Abhängigkeiten verfügbar sind.

Ist es nicht eine schlechte Praxis, das zu installierende Paket nicht von setup.py importieren? Es gibt viel bessere Möglichkeiten, die Paketversion an einem Ort zu verwalten, z. B. wie in diesem Verpackungshandbuch von PyPA beschrieben.

In der Diskussion in pypa / setuptools # 1642 hofften @uranusjr und ich beide, dass dies eine Gelegenheit sein könnte, die Leute dazu zu bringen , sich nicht mehr auf die Tatsache zu verlassen, dass . in sys.path wenn Sie a ausführen Python-Skript, und beginnen Sie, Menschen in eine explizitere Semantik zu versetzen.

Das Hauptproblem hierbei ist, dass durch das bloße Vorhandensein von pyproject.toml Personen sowohl für PEP 518 als auch für PEP 517 ausgewählt werden. Selbst wenn Sie kein Build-Backend angegeben haben, erhalten Sie plötzlich die neue Semantik.

Ist diese Entscheidung von pip zu diesem Zeitpunkt irreversibel? Vielleicht können Sie sich mit pyproject.toml für PEP 518 anmelden, aber PEP 517 wird nur ausgelöst, wenn Sie tatsächlich ein Build-Backend angeben?

Ehrlich gesagt ist es eine schwierige Situation, aber ich denke, es ist für pip einfacher, davor zu warnen, als für setuptools . Wenn wir PEP 517 vorerst aktivieren und sagen, dass das Vorhandensein von pyproject.toml PEP 517 nach 20.0 oder 21.0 auslöst, können wir einen Migrationsleitfaden erstellen und Warnungen in pip ausgeben. build-backend fehlt in pyproject.toml Beachten Sie, dass die Build-Isolation nach Version 21.0 standardmäßig setuptools.build_meta finden Sie im Migrationshandbuch unter ..."

Ist es nicht eine schlechte Praxis, das zu installierende Paket nicht von setup.py importieren? Es gibt viel bessere Möglichkeiten, die Paketversion an einem Ort zu verwalten, z. B. wie in diesem Verpackungshandbuch von PyPA beschrieben.

Um fair zu sein, definiert dieser Leitfaden das Importieren des zu installierenden Pakets von setup.py als Strategie 6, also ist es definitiv etwas üblich. Wenn wir uns zu diesem Zeitpunkt von dieser Art von Strategie entfernen, sollte diese Seite aktualisiert werden, damit sie nicht mehr enthalten ist.

Die Entscheidung, PEP 517 bei Existenz von pyproject.toml auszulösen, war eine bewusste Entscheidung (die Diskussion befasste sich wahrscheinlich mit dem Implementierungsproblem von PEP 517 oder der PR, aber ich habe momentan keine Zeit, es zu finden). Natürlich könnte es im Lichte dessen, was wir hier sehen, geändert werden, aber wir sollten dies nicht tun, ohne die Gründe zu berücksichtigen, aus denen wir unsere Entscheidung getroffen haben.

Pip selbst prüft nicht (sollte nicht, IMO), ob setup.py richtig ist, um anzunehmen, dass sich das Projektverzeichnis auf sys.path , daher zögere ich etwas, pip einfach zu ändern weil setuptools einen anderen Standardwert verwenden möchte, wenn das Backend verwendet wird. Ich bin damit einverstanden, dass das Importieren des Projekts, das in setup.py wird, eine Reihe von Schwierigkeiten hat, aber es ist nicht so, dass es bisher Warnungen ausgelöst hat, daher hatte ich angenommen, dass das Backend diese Semantik beibehalten sollte. Anders ausgedrückt, selbst wenn pip wie von Ihnen vorgeschlagen warnte, warum sollten Benutzer "Build Isolation verwendet standardmäßig setuptools.build_meta " lesen, um zu implizieren, dass Sie Ihr Projekt nicht aus setup.py importieren können

Persönlich stimme ich dem aktuellen Ansatz zu, mich auf die Existenz der Datei pyproject.toml zu verlassen. Die Probleme, die IMO mit sich bringt, stammen von Personen, die pyproject.toml für andere Zwecke als zum Verpacken verwenden. Der richtige Ausweg besteht daher darin, Tools ohne Verpackung zu verwenden, um eine andere Möglichkeit für die Konfiguration anzubieten, sodass Benutzer entscheiden können, ob sie pyproject.toml verwenden möchten oder nicht.

Pip selbst prüft nicht (sollte nicht, IMO), ob setup.py zu Recht davon ausgeht, dass sich das Projektverzeichnis auf sys.path befindet. Daher zögere ich etwas, pip zu ändern, nur weil setuptools a pushen möchte andere Standardeinstellung, wenn das Backend verwendet wird.

Es ist nur so, dass pip ausgeht, dass das Aufrufen der setuptools.build_meta Hooks dem Aufrufen von setup.py entspricht und entsprechen sollte. Wir haben bereits Fälle gesehen, in denen dies nicht der Fall ist, und ich denke, es muss noch festgestellt werden, ob wir ( setuptools ) wollen, dass der Vertrag von setuptools.build_meta "dies entspricht dem Aufruf von python setup.py "oder wenn wir stattdessen möchten, dass es" dies ist eine abgesperrtere und isoliertere Version des direkten Aufrufs von setup.py ".

Natürlich könnte setuptools sagen "das ist nicht der Vertrag der Funktion, also werden wir ihn nicht reparieren" und pip könnte sagen "unsere Entscheidung war, dass es standardmäßig PEP 517 ist" und Wir können beide sagen, dass der Fehler im anderen Projekt liegt, aber es ist wahrscheinlich eine gute Idee, ihn zu koordinieren.

Anders ausgedrückt, selbst wenn pip wie von Ihnen vorgeschlagen warnte, warum sollten Benutzer "Build-Isolation verwendet standardmäßig setuptools.build_meta" lesen, was bedeutet, dass Sie Ihr Projekt nicht aus setup.py importieren können? Die beiden Tatsachen scheinen mir nichts zu tun zu haben ...

Sie können verwandt sein oder nicht, aber es kann auch andere Änderungen an der Semantik geben. Der Sinn einer solchen Warnung lautet: "Bitte geben Sie ausdrücklich an, wie dieser Build ausgeführt werden soll, da wir Sie bald für etwas entscheiden werden, das Ihren Build beschädigen könnte." Projekte können das Build-Backend vorzeitig zu ihren pyproject.toml hinzufügen und eventuell auftretende Fehler proaktiv beheben.

Wir könnten möglicherweise auch ein "Dummy" -PEP 517-Backend in setuptools wie setuptools.build_meta_legacy erstellen, das nur chdir s in das Stammverzeichnis einfügt und auf diese Weise setuptools.build_meta aufruft Menschen können sich nur dann für das alte Verhalten entscheiden, wenn sie es brauchen, bevor es zu brechen beginnt.

Persönlich stimme ich dem aktuellen Ansatz zu, mich auf die Existenz der Datei pyproject.toml zu verlassen. Die Probleme, die IMO mit sich bringt, stammen von Personen, die pyproject.toml für andere Zwecke als zum Verpacken verwenden.

Ich denke, wir müssen PEP 517 und PEP 518 trennen. PEP 518 listet explizit die "Standardwerte" für den PEP auf, während PEP 517 nichts über das Standard-Backend angibt.

Ich erinnere mich, dass ich mich dem Ganzen nicht schrecklich abgeneigt fühlte, "die Existenz von pyproject.toml Sie, Isolation aufzubauen", aber in der Praxis mag ich auch nicht die Idee, dass die Angabe der Abhängigkeiten meines isolierten Builds ebenfalls eine Option wäre mich in setuptools.build_meta .

Möglicherweise besteht die Lösung darin, die Differenz aufzuteilen und das Backend standardmäßig auf ein nicht dokumentiertes setuptools.build_meta_legacy (wodurch versucht wird, die Semantik von setup.py beizubehalten). Auf diese Weise können wir zumindest feststellen, ob ein Benutzer eine positive Entscheidung für die Verwendung der neuen Semantik getroffen hat oder ob er einfach nicht darüber nachgedacht hat.

Ein build_meta_legacy mit einer Warnmeldung klingt für mich nach einer vernünftigen Lösung. Es ist wahrscheinlich besser, die Warnung besonders hervorzuheben (z. B. während der Installation und die Benutzer zu ermutigen, dies als Fehler beim Betreuer einzureichen) und klare Anweisungen zu geben, wie die Migration durchgeführt werden soll.

Ich sollte auch beachten, dass Pips Absicht (das ist der "Corporate" -Pip ;-) - ich meine, dass die Pip-Entwickler dies ein wenig diskutierten und zu einem allgemeinen Konsens kamen, dass es sich nach einer vernünftigen Idee anhörte, aber es ist noch kein fester Plan und es hängt davon ab, dass jemand tatsächlich Code schreibt, damit dies geschieht.) Wir wechseln relativ schnell dazu, alle Projekte über PEP 517 zu übergeben und unseren alten Codepfad insgesamt durch setup.py löschen. Wenn Sie das Setuptools-Backend nur in Pip 21.0 erstellen (um die empfohlene Version von oben zu verwenden), wird dies um mindestens weitere 2 Jahre verschoben.

Während PEP 517 nichts über das Standard-Backend angibt

Wahr. Aber irgendwann wird pip den Sonderfall Unterstützung von Setuptools fallen. Das ist schließlich der springende Punkt (zumindest für uns) von PEP 517, das Frontend vom Backend zu entkoppeln und alle Backends gleich zu stellen. Wenn wir das tun, müssen wir entweder einen Fehler machen, wenn es kein Backend gibt, oder einen Standard auswählen (und wir werden aus alten Gründen standardmäßig setuptools verwenden). Die Debatte hier ist, wenn wir das tun, nicht wenn.

Pip verfügt derzeit über zwei Codepfade für Installationen - den PEP 517-Pfad und den Legacy-Pfad setup.py . Dies ist eine Quelle für Wartungsprobleme und potenzielle Fehler. Wir haben uns dafür entschieden, PEP 517 als Standard festzulegen, wenn pyproject.toml vorhanden war, um die Verwendung des PEP 517-Pfads sicherzustellen (es ist unwahrscheinlich, dass Projekte schnell build-backend = setuptools.buid_meta hinzufügen. Ohne das aktuelle Verhalten stehen die Chancen also gut Das Testen des PEP 517-Codes beider Pip und des Backends von setuptools würde über einen längeren Zeitraum nahe Null bleiben. Es gibt ein Opt-out in Form von --no-use-pep517 , um genau den (angenommenen seltenen) Fällen gerecht zu werden, in denen das Setuptools-Backend ungeeignet war.

Ich glaube nicht, dass irgendjemand damit gerechnet hat, dass Setuptools semantische Unterschiede zwischen setup.py und dem Backend haben möchten, also die Möglichkeit, dass --no-use-pep517 benötigt wird, um semantische Unterschiede so oft zu umgehen, wie es sein sollte Die Standardeinstellung wurde nie berücksichtigt.

Wir könnten möglicherweise auch ein "Dummy" -PEP 517-Backend in Setuptools wie setuptools.build_meta_legacy erstellen, das nur in das Stammverzeichnis chdiriert und setuptools.build_meta aufruft. Auf diese Weise können sich Benutzer nur dann für das alte Verhalten entscheiden, wenn sie es benötigen, bevor es zu brechen beginnt .

Das kann eine vernünftige Lösung sein. Aber es müsste zumindest teilweise dokumentiert werden - zumindest würde pip dokumentieren, dass dies der Standardwert ist, den wir annehmen würden. Ob Setuptools das Backend ohne Papiere gelassen haben, ist wohl ihre Wahl.

Ich bin mir nicht sicher, wie nützlich eine weitere theoretische Diskussion ist. Ich glaube nicht, dass ich noch etwas hinzufügen muss. Ich würde vorschlagen, dass, wenn jemand dies vorantreiben möchte, der beste Weg darin besteht, eine PR zu erstellen, die die Standardeinstellung umschaltet, und die Diskussion darüber, ob wir sie akzeptieren möchten, dorthin übergehen kann.

Für Paketbetreuer, die dieses Problem für Ihre Benutzer beheben möchten: Ich habe einen Shim veröffentlicht, der den Fix sys.path implementiert.

https://pypi.org/project/setuptools-localimport/

Hoffentlich kann dies als Notlösung funktionieren, damit wir darüber nachdenken können, wie dies vorangebracht werden sollte, ohne in eine Lösung zu stürzen, oder die Einführung von Pip 19.0 (das viel mehr Extras als nur PEP 517 enthält) unnötig verlangsamen.

Ich habe einen Shim veröffentlicht, der den Fix sys.path implementiert.

Das ist großartig! Unabhängig von der endgültigen Lösung ist dies ein wirklich schönes Beispiel für die Flexibilität des PEP 517-Hakensystems :-)

Ich habe es behoben, indem ich meine Pip-Version unter 19.x heruntergestuft habe. Dann habe ich versucht, sie zu installieren und bin erfolgreich gegangen

Es gibt einen dritten Anwendungsfall: Was ist mit Paketen, die ein eigenes Build-Backend bereitstellen? Beispiel: setuptools selbst listet nur wheel als Build-Anforderung auf:

[build-system]
requires = ["wheel"]
build-backend = "setuptools.build_meta"

Dies schlägt natürlich fehl, wenn der Code von pip für die Behandlung von PEP 517 das Quellverzeichnis nicht zu sys.path hinzufügt.

Aus PEP 517:

Beim Importieren des Modulpfads wird nicht in das Verzeichnis gesucht, das den Quellbaum enthält, es sei denn, dies befindet sich ohnehin in sys.path (z. B. weil es in PYTHONPATH angegeben ist). Obwohl Python in einigen Situationen das Arbeitsverzeichnis automatisch zu sys.path hinzufügt, sollte der Code zum Auflösen des Backends davon nicht betroffen sein.

Das sagt mir (ziemlich klar), dass Projekte beim Auflösen von build-backend nicht erwarten sollten, dass sie ihr eigenes Projektverzeichnis sehen können - daher muss sich setuptools zu requires IMO hinzufügen. Und ja, ich verstehe, dass dies kreisförmig ist. Aber Build-Backends, die sich selbst erstellen, sind von Natur aus sowieso ziemlich kreisförmig - sie sind sicherlich nicht der Normalfall.

Dieser Abschnitt scheint mir auch zu bestätigen, dass Build-Tools nicht erwarten sollten, dass sich das Projektverzeichnis im sys.path der Build-Umgebung befindet.

Wie würde das mit --no-binary :all: funktionieren?

@pfmoore Eine Variante der Situation ist, dass ein Paket ein benutzerdefiniertes Build-System bereitstellt. Das Build-System ist nicht installiert (und nicht Teil des bdist), sondern wird mit dem sdist geliefert, um möglicherweise einen Build-Prozess zu vereinfachen. Ist dies ein gültiger Anwendungsfall oder muss der Betreuer das benutzerdefinierte Build-System als separates Paket veröffentlichen?

Edit: So etwas wie

project/
    custom_build.py
    src/
        my_package/
            __init__.py
            ...
    pyproject.toml  
[build-system]
requires = []
build-backend = "custom_build"

# Maybe the custom backend specifies metadata like this…
[tool.custom_build.metadata]
name = "my-package"
dependencies = []
packages = ["my_package"]

Vielleicht wäre eine Lösung, eine neue optionale Konfiguration hinzuzufügen, um anzugeben, wo während des Builds Module zu finden sind?

[build-system]
requires = []
build-backend = "custom_build"
build-backend-findpath = ["build_systems"]   # Put custom_build.py above in a subdirectory.

Die Konfiguration ist standardmäßig [] (leere Liste), was bedeutet, dass keine Pfade hinzugefügt werden (dh dasselbe wie das aktuelle Verhalten), aber Projekte können Pfade hinzufügen, um das Build-System lokal zu finden.

Wenn build-system vollständig weggelassen wird, lautet der Abschnitt standardmäßig:

requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
build-backend-findpath = [""]

pip kann eine Warn- / Infomeldung anzeigen, um den Benutzer zur Migration aufzufordern (wahrscheinlich mit einem Link zu einer Dokumentationsseite).

Ein zusätzlicher Vorteil dieser Lösung besteht darin, dass alles in pip erledigt werden kann (eigentlich das verkaufte pep517-Modul). An Setuptools oder vorhandenen defekten Projekten muss sich nichts ändern.

Eine Variante der Situation besteht darin, dass ein Paket ein benutzerdefiniertes Build-System bereitstellt.

Ich weiß es ehrlich gesagt nicht. Es ist keine Situation, an die ich gedacht habe. Ich weiß nicht, ob die PEP-Autoren darüber nachgedacht haben - ich erinnere mich an keine Diskussion über die Angelegenheit, als das PEP entwickelt wurde.

Nach der Überprüfung sagt PEP 517 tatsächlich explizit (im Abschnitt zu build-backend ): "Beim Importieren des Modulpfads suchen wir nicht in dem Verzeichnis, das den Quellbaum enthält, es sei denn, dies wäre ohnehin auf sys.path "Was für mich bedeutet, dass ausdrücklich davon abgeraten wird, Backends im Baum zu haben. Ob jemand dies mit ausreichend verschlagenem Code umgehen könnte, weiß ich nicht genau (aber ich vermute nicht).

Der erwartete Anwendungsfall bei der Entwicklung von PEP 517 war, dass Backends als Räder auf PyPI (oder einem benutzerdefinierten Index) ausgeliefert und in die Build-Umgebung installiert werden. Die Art und Weise, wie Backends erstellt wurden, lag ausdrücklich außerhalb des Anwendungsbereichs. Meine persönliche Vermutung war, dass sie nicht die PEP 517-Mechanismen verwenden, sondern einen Befehl auf niedrigerer Ebene (z. B. setup.py bdist_wheel oder flit build ). Die rekursive Verwendung eines PEP 517-Backends zum Erstellen selbst schien ein zu komplexer Schritt zu sein. Es wurde als Teil der PEP 518-Implementierung in Pip betrachtet (es gibt einen potenziellen Gabelbomben-Exploit, wenn ein Backend als SDIST ausgeliefert wird und sich selbst erstellt, was wir verhindern mussten, bevor wir Backends unterstützen konnten, die nicht als Räder verteilt waren ) aber nur im Zusammenhang mit dem Herunterladen des Backends von PyPI.

tl; DR; Alles, was ich anbieten kann, ist meine Erinnerung an die damaligen Diskussionen - vielleicht durchsuchen Sie die Archive besser nach dem tatsächlichen Hintergrund.

Ich weiß nicht, ob die PEP-Autoren darüber nachgedacht haben - ich erinnere mich an keine Diskussion über die Angelegenheit, als das PEP entwickelt wurde.

Ich habe gerade angefangen, mir die Archive anzusehen, und es scheint, dass diese Frage gegen Ende des Prozesses (oder zumindest bis in die Tiefe hinein) tatsächlich ausführlich diskutiert wurde. Ich weiß nicht, welche Website am besten zum Anzeigen der Archive geeignet ist, aber hier ist ein Punkt, an dem die Diskussion wieder über diese Frage spricht (28. Juli 2017):
https://mail.python.org/pipermail/distutils-sig/2017-July/031109.html
https://www.mail-archive.com/[email protected]/msg26624.html

Zum Beispiel endet diese bestimmte E-Mail mit ...

Angesichts der Probleme, die wir bereits mit PEP 517 haben, ist es möglicherweise sinnvoller, wenn PEP 517 nur vorschreibt, dass sich das Verzeichnis nicht auf sys.path befindet, und ein kleines Folge-PEP nur für den Python-Pfad erstellt.

Ich werde Sie wissen lassen, ob ich auf das endgültige Urteil stoße, aber ich ermutige andere, selbst zu lesen.

Nett! Danke, dass du das gefunden hast :-)

Also habe ich ein paar E-Mails überflogen und ich denke, Sie können zumindest bis zum 29. August weitermachen, wo Nick anscheinend darauf hinweist, dass Konsens darüber besteht, das Quellverzeichnis _out_ von sys.path zu verlassen:
https://mail.python.org/pipermail/distutils-sig/2017-August/031413.html
(Einer nach dem anderen wurden die Leute von Nathaniels Argumenten überzeugt.)

In derselben oben verlinkten E-Mail sagt Nick jedoch Folgendes :)

  1. Wenn das Weglassen wirklich ein Problem ist, werden wir es wahrscheinlich früh genug im Rahmen der Implementierung eines setup.py-Backends herausfinden

Hier ist ein ausführlicherer Absatz aus der E-Mail:

Ich denke, wir können davon ausgehen, dass dieses Problem zugunsten von "Frontends müssen sicherstellen, dass sich das aktuelle Verzeichnis NICHT auf sys.path befindet, bevor das angegebene Backend importiert wird" gelöst wird. Wenn wir dort beginnen, maximieren wir unsere Chancen, als Teil der Initiale etwas Neues zu lernen Rollout der vorläufig akzeptierten API.

Ich weiß noch nicht, ob es spätere E-Mails gibt, die diese Zusammenfassung ändern, aber es gibt nicht viele E-Mails zum Thema danach.

Vielen Dank, dass Sie die Archive für uns @cjerdonek durchsucht haben. Angabe meines derzeitigen Verständnisses des Problems:

  1. Viele reale setup.py -Dateien gehen derzeit davon aus, dass sich das aktuelle Verzeichnis bei der Ausführung auf sys.path , was zu seltsamen Bootstrapping-Problemen führt, da Projekte sich selbst als Abhängigkeit von der Installationszeit behandeln
  2. PEP 517 besagt ausdrücklich, dass Build- Frontends das aktuelle Verzeichnis nicht implizit zu sys.path hinzufügen sollten (es sagt nichts über Backends aus).
  3. pip 19.0 betrachtet pyproject.toml ohne einen build-system Abschnitt als äquivalent zu einem build-system Abschnitt, der das setuptools Backend angibt
  4. Das setuptools PEP 517-Backend fügt das aktuelle Verzeichnis derzeit auch nicht zu sys.path (da das Verlassen von Punkt 1 oben als wünschenswertes zukünftiges Ziel angesehen wird).
  5. Für vorhandene Projekte stehen zwei vorläufige Problemumgehungen zur Verfügung, während das Standardverhalten verbessert wird: Fixieren von pip auf weniger als 19.0 und explizites Festlegen der Option --no-use-pep517 . Die Leute entdecken diese jedoch erst, nachdem sie zum ersten Mal entdeckt haben, dass ein Upgrade von pip ihre Builds zerstört.

Aus funktionaler Sicht denke ich, dass die wichtigste Änderung, die wir einführen möchten, darin besteht, dass im Fall " pyproject.toml ohne build-system Abschnitt" das Verzeichnis mit setup.py enden sollte wieder auf sys.path . Es gibt zwei Möglichkeiten, damit umzugehen:

  1. Holen Sie sich pip , um es zu tun. Dies hat den unglücklichen Nebeneffekt, dass das Verhaltens-Front-End abhängig wird und möglicherweise vorhandene Projekte nicht installiert werden können, es sei denn, alle Frontends implementieren dieselbe Problemumgehung
  2. Holen Sie sich das setuptools PEP 517-Backend, indem Sie pyproject.toml auf einen Abschnitt build-system und das Verzeichnis setup.py in sys.path wenn sowohl der Abschnitt als auch der Pfadeintrag fehlen. In dieser Situation wird immer noch ein neues pip benötigt, da eine Mindestversion von Setuptools angegeben werden muss, die den Fall "no build-system section" korrekt behandelt.

Um die Dinge für Endbenutzer so schnell wie möglich zum Laufen zu bringen, ohne uns in unglückliche Designecken zu streichen, würde ich tatsächlich eine dreistufige Lösung vorschlagen:

  1. Führen Sie jetzt eine neue Veröffentlichung von pip (19.0.1?) Durch, die den zusätzlichen Eintrag sys.path für den Fall "no build-system entry" hinzufügt. Zu diesem Zeitpunkt sollte das Kompatibilitätsproblem für Endbenutzer weitgehend behoben sein.
  2. Führen Sie eine neue Version von setuptools , die den Zusatz sys.path behandelt, sofern das Frontend dies noch nicht getan hat.
  3. Ändern Sie in einer späteren Version von pip den Fall "no build-system entry", um das spezielle Gehäuse zu entfernen, und legen Sie stattdessen eine strengere Mindestversion für setuptools .

Dieser Vorschlag basiert auf der Tatsache, dass ich denke, dass das setuptools PEP 517-Backend der "richtige" Ort ist, um setup.py Abwärtskompatibilitätsprobleme zu lösen, aber ich denke auch, dass pip optimiert wird Direkt ist wahrscheinlich in naher Zukunft eine viel einfachere Änderung, und diese Änderung wird das Problem enthalten, während an dem architektonisch vorzuziehenderen Fix gearbeitet wird.

Ich habe das build_meta_legacy Backend in pypa / setuptools # 1652 erstellt. Ich würde es wirklich vorziehen, wenn pip auf die Verwendung von setuptools.build_meta_legacy als Standard-Backend umsteigen würde, aber ich denke, das Erstellen eines integrierten "Legacy Shim" -Backends ist ungefähr so ​​weit, wie ich es mir bequem mache in setuptools . Ich möchte nicht auf unbestimmte Zeit stecken bleiben und die vollständige " python setup.py install Emulation" im Haupt-Backend von setuptools PEP 517 unterstützen.

Ich bin ein bisschen verwirrt, warum setuptools nicht emulieren möchte, dass das Skript hier nativ ausgeführt wird. TBH. Es scheint, als würden Endbenutzer verwirrt, wenn python setup.py bdist_wheel korrekt funktioniert, pip wheel jedoch nicht (vorausgesetzt, sie haben das Backend für nicht ältere Builds festgelegt).

Was ist die Begründung?

Was ist die Begründung?

Mein langfristiger Plan ist es, jeden direkten Aufruf von setup.py zugunsten eines indirekten Aufrufs durch PEP 517-Frontends oder etwas Äquivalentes (für andere Befehle) abzulehnen. Wenn wir in eine Welt mit "allen isolierten Umgebungen" wechseln, möchte ich nicht gezwungen werden, die Semantik von setuptools Befehlsaufrufen aus demselben Grund wie PEP mit dem Aufrufen von python setup.py kompatibel zu halten 517 sagte ausdrücklich, dass Frontends dies nicht tun sollten - es hat das Potenzial, die Build-Isolation zu durchbrechen und im Allgemeinen unerwünschte Situationen zu schaffen.

Ich denke, es ist ziemlich selten, dass dies benötigt wird, außer als Teil eines Anti-Musters. Jeder, der ein berechtigtes Bedürfnis danach hat, kann sys.path in seinem Setup-Skript ziemlich einfach manipulieren.

Nur als Hinweis, ich glaube nicht, dass PEP 517 jemals als Entwurfsziel hatte, dass der gesamte Zugriff auf Build-Tools über die Hooks möglich wäre. Zum Beispiel hat flit seine eigenen Befehle flit build usw., und es gibt keine Absicht, die mir bewusst ist, diese zu verwerfen. Es ist also möglich, dass Sie Randfälle finden, in denen die Absicht hinter PEP 517 darin bestand, dass werkzeugspezifische Befehle verwendet werden mussten. Ein offensichtliches Beispiel ist das Erstellen des Backends selbst (wie oben erwähnt), aber es gibt auch andere Fälle (derzeit nicht standardisiert, obwohl zukünftige PEPs möglicherweise Hooks hinzufügen), wie bearbeitbare Installationen und In-Place-Builds (Wiederverwendung von Artefakten aus früheren Builds).

Die Einigung darüber zu erzielen, dass alle Tools "Build SDIST" und "Build Wheel" unterstützen könnten, war so schwierig, dass ich nicht damit rechne, die Liste der Standardoperationen bald weiter zu erweitern.

Nur als Hinweis, ich glaube nicht, dass PEP 517 jemals als Entwurfsziel hatte, dass der gesamte Zugriff auf Build-Tools über die Hooks möglich wäre.

Dies ist nicht das, was ich vorgeschlagen habe, und es ist ein bisschen ein Exkurs. Mein Punkt war, dass die Probleme, die PEP 518 erforderlich machten, auch allgemeiner für alle setup.py -Befehle bestehen, und diese lassen sich am besten lösen, indem die Leute davon abgehalten werden, setup.py überhaupt aufzurufen. Dazu ist kein Standard erforderlich. flit benötigt kein PEP, um Unterbefehle hinzuzufügen.

Ah, OK. Entschuldigung für das Missverständnis.

@ncoghlans vorgeschlagener Übergang scheint mir gut zu sein. Wenn niemand Probleme damit hat, lassen Sie uns fortfahren.

Vielen Dank für das Ausgraben der Archive @cjerdonek!

Da es bereits eine PR gibt, die dies in Setuptools behebt (durch die Einführung des Legacy-Backends). Gibt es einen Grund, Schritt 1 oben nicht zu überspringen? Wir installieren setuptools in einer isolierten Build-Umgebung, daher sollte es abhängig von einer sehr aktuellen Version kein Problem sein.

Gibt es einen Grund, Schritt 1 oben nicht zu überspringen?

Nee. Wir können die aktuell erforderliche Mindestversion direkt anstoßen.

Mein Übergangsplan basiert auf der Annahme, dass die Leute mehr Zeit benötigen, um den langlebigen Übergangsmechanismus auf der Seite von setuptools während @pganssles dediziertes Übergangs-Backend in dieser

Trotzdem bin ich nicht mit den Details der Funktionsweise der PEP 517-Implementierung in pip vertraut. Daher ist meine Annahme, dass das Problem im Front-End einfach zu umgehen ist, möglicherweise falsch.

Da Backends in einem Unterprozess ausgeführt werden (und tatsächlich das verkaufte Projekt pep517 , das eine zusätzliche Indirektionsebene hinzufügt), ist mir überhaupt nicht klar, wie wir sys.path für festlegen würden ein Backend-Hook. Zumindest müssten wir PYTHONPATH einbeziehen, was bedeutet, dass wir uns Gedanken über Fälle machen müssen, in denen der Benutzer bereits PYTHONPATH festgelegt hat und wie der Isolationscode diese verwendet.

Im Wesentlichen ist das Setzen von sys.path in pip, wie ich vermute, eindeutig nicht trivial. Es ist unwahrscheinlich, dass ich Zeit habe, mich mit den Details zu befassen, geschweige denn selbst einen Patch zu schreiben (und sicherzustellen, dass er ordnungsgemäß getestet wurde!).

Ich denke, ein festes Setuptools-Backend ist der schnellste Weg nach vorne.

Mein langfristiger Plan ist es, jeden direkten Aufruf von setup.py zugunsten eines indirekten Aufrufs durch PEP 517-Frontends oder etwas Äquivalentes (für andere Befehle) zu verwerfen.

@pganssle autsch . Prozedural setup.py muss sterben. Es sollte aus keinem Grund existieren. Weil diese "Flexibilität" eine endlose Quelle von Schmerzen und Zusammenbrüchen ist. Es ist unmöglich, setup.py und damit alle Probleme mit der Python-Verpackung zu migrieren.

Ich würde setup.py durch package.json ersetzen und einfach einen Python-Abschnitt dafür hinzufügen, anstatt ein weiteres Paketbeschreibungsformat.

Zumindest kann ich dann ==1.x Versionsspezifizierer verwenden .

@techtonik Bitte geh weg. Ihre nicht konstruktiven Beiträge bleiben in jedem Projekt, an dem ich teilnehme, unerwünscht.

Durch die Arbeit an # 6210 konnte ich meine eigene Frage von oben beantworten, wie schwierig es sein wird, dies auf der Ebene von pip beantworten: Die Herausforderung besteht darin, dass die Informationen darüber, ob das Quellverzeichnis als sys.path[0] eingefügt werden soll oder nicht pyproject.toml liest, bis zum PEP 517-Hook-Aufrufer und von dort in das eigentliche In-Process-Wrapper-Skript getunnelt werden.

Diese sind ohne größere architektonische Änderungen möglich (ein pip._implicit. -Präfix im Build-Backend-Namen für den ersten Teil und ein PEP517_SYS_PATH_0 env var für den letzteren Teil), aber es bedeutet, das verkaufte pep517 vorübergehend zu ändern setuptools fertig ist.

Mein Übergangsplan basiert auf der Annahme, dass die Leute mehr Zeit benötigen, um den langlebigen Übergangsmechanismus auf der Setuptool-Seite zu erarbeiten, während das dedizierte Übergangs-Backend von @pganssle in dieser

Ja, dem stimme ich zu. Ich habe genau dies in einem Distutils-Post vorgeschlagen. Es gibt zwei Dinge, die ich für wichtig halte:

  1. So schnell wie möglich eine Lösung für Benutzer finden
  2. Den richtigen Übergang finden.

Ich persönlich denke, dass es das Richtige ist, die Existenz von "pyproject.toml" zu entfernen, bis die Übergangslogik vorhanden ist. In Anbetracht der Tatsache, dass die Änderungen an setuptools Konsequenzen für die öffentlich zugängliche API haben und in pip nur die Verzögerung verzögern würden, die sich als rückwärts inkompatible Änderung herausgestellt hat, ist dies für mich sinnvoll Führen Sie die Schnellkorrektur in pip während wir den Weg nach vorne für setuptools überprüfen.

Mit beiden Ansätzen auf meinem lokalen Computer habe ich sowohl # 6210 als auch # 6212 gegen die ursprüngliche problematische PyInstaller==3.4 -Anforderung getestet.

Ich weiß nicht, ob der Fehler # 6212 ein Test-Setup-Problem ist oder ob es tatsächlich ein weiteres Problem in der Setuptools-Vorabversion gibt. Ich weiß nur, dass weitere Integrationsarbeiten durchgeführt werden müssen, bevor wir uns auf diese Lösung verlassen können. Ich bin jetzt zuversichtlich in # 6210 - das einzige, was daran falsch ist, ist, dass es ein schrecklicher Kompatibilitäts-Hack ist, den wir nicht wollen, dass pip für immer tragen muss.

Es sieht so aus, als ob --no-cache für das fehlgeschlagene assert auf # 6212 verantwortlich ist. Das Testen mit --cache-dir ergab stattdessen einen erfolgreichen lokalen Test: https://github.com/pypa/pip/pull/6212#issuecomment -458166386

(Ich werde für ~ 18 Stunden offline sein, um zu schlafen und zu arbeiten, also sollten die Leute sich frei fühlen, mit dem zu laufen, was in der Zwischenzeit # 6210 oder # 6212 Sinn macht)

Ich habe den Titel aktualisiert, um die Situation besser widerzuspiegeln. Danke @ncoghlan für die PRs!


Moderationshinweis: Ich habe auch die unproduktiven Kommentare (und die Antworten darauf) als "Off Topic" ausgeblendet und werde dies für zukünftige Kommentare in dieser Richtung tun. Wenn jemand eine Diskussion über die Moderation haben möchte, reichen Sie ein neues Problem ein oder senden Sie mir eine E-Mail. Dieser Thread ist nicht der richtige Ort, um Probleme mit der Moderation anzusprechen, die Sie möglicherweise haben.

Ich habe dies auch angeheftet, um zu vermeiden, dass Leute Duplikate erstellen, und um klar zu signalisieren, dass wir darüber Bescheid wissen.

Selbst wenn wir pep517 aktivieren, ist dies eine Verhaltensänderung, die nicht angekündigt wurde und daher Bibliotheken zerstört, selbst wenn sie sich bereits angemeldet haben (siehe z. B. PyInstaller ). In dem Fall, in dem eine Bibliothek ein Opt-In für pep517-Builds deklariert und _ und_ Dinge lokal importiert, die voraussichtlich auf sys.path finden sind, wird von pip keine Annahme getroffen (da die Bibliothek explizit ist), die Bibliothek jedoch immer noch plötzlich kaputt.

In diesem Fall sehe ich wirklich keine Alternative, außer nur cwd in Setuptools aufzunehmen, weil dies nur kaputt ist. Wenn der Vorschlag nicht darin besteht, die Leute anzuweisen, die zwischen pep517 und pip 19 geschnittenen Releases zu reparieren, die, wenn ein Benutzer diese Versionen streng fixiert hat, plötzlich nicht mehr installierbar sind, sollten wir die Auswirkungen in Betracht ziehen dieser Entscheidungen auf die Benutzererfahrung. Basierend auf dieser Diskussion und den aktuellen Vorschlägen können einige dieser Bibliotheken nicht mit neuen Versionen von pip + setuptools installiert werden, die die Standardeinstellungen verwenden, es sei denn, pep517-Builds sind explizit deaktiviert.

Dies ist ziemlich wirkungsvoll, wenn Sie nur versuchen, ein Paket mit dem Tool zu installieren, das Ihnen von Python zur Verfügung gestellt wird, aber tatsächlich kann es die Dinge nicht zufällig installieren. Ich sage dies, um den Fokus für einen Moment von den technischen Aspekten auf die Auswirkungen auf den Endbenutzer zu lenken, der möglicherweise mit den Werkzeugen, dem Ökosystem, den Bibliotheken oder der Sprache selbst frustriert ist, weil plötzlich (und ja, nur unter) bestimmte Umstände), Dinge, die sie jetzt gut installieren könnten, können nicht installiert werden. Ich denke wirklich, wir sollten diese Lücke in jeder implementierten Lösung schließen.

Wir verwenden derzeit einen Fehlerstapel, um fehlgeschlagene Installationen in pipenv zu behandeln, und ich füge --no-use-pep517 wenn verfügbar, um Fehler aufgrund dieser Änderungen zu behandeln. Ich bin mir nicht sicher, ob dies für den Durchschnittsbenutzer intuitiv sein wird, da wahrscheinlich nicht einmal sofort klar ist, woran das Problem liegt. Ich sage dies nur, um darauf hinzuweisen, dass wir eine Problemumgehung haben, aber es ist wichtig, diese Lücke zu schließen, um den Benutzern ein wenig dabei zu helfen

(edit: auch ein großes Dankeschön an pganssle, cjerdonek, pfmoore, pradyunsg, ncoghlan und alle anderen, die viel Zeit und Mühe darauf verwendet haben)

Der erwartete Anwendungsfall bei der Entwicklung von PEP 517 war, dass Backends als Räder auf PyPI (oder einem benutzerdefinierten Index) ausgeliefert werden, die heruntergeladen und in die Build-Umgebung installiert werden. Die Art und Weise, wie Backends erstellt wurden, lag ausdrücklich außerhalb des Geltungsbereichs. Meine persönliche Vermutung war, dass sie nicht die PEP 517-Mechanismen verwenden würden, sondern einen Befehl auf niedrigerer Ebene (z. B. setup.py bdist_wheel oder flit build). Die rekursive Verwendung eines PEP 517-Backends zum Erstellen selbst schien ein zu komplexer Schritt zu sein. Es wurde als Teil der PEP 518-Implementierung in Pip betrachtet (es gibt einen potenziellen Gabelbomben-Exploit, wenn ein Backend als SDIST ausgeliefert wird und sich selbst erstellt, was wir verhindern mussten, bevor wir Backends unterstützen konnten, die nicht als Räder verteilt waren ) aber nur im Zusammenhang mit dem Herunterladen des Backends von PyPI.

Um noch einmal darauf zurückzukommen: Die neue Standardeinstellung setuptools.build_meta_legacy löst das Problem bei der Verwendung von PEP 517 für alles außer für PEP 517-Backends, das für setuptools selbst ein Problem darstellt. Wenn wir das nicht lösen, ist es, wie @ benoit-pierre in pypa / setuptools # 1644 hervorhebt, nicht möglich, pip install --no-binary :all: für ein Projekt zu verwenden, das von setuptools abhängt (oder vermutlich ein PEP 517-Backend-Anbieter).

Sollten wir das in diesem Thread diskutieren oder einen neuen Thread erstellen, um es zu diskutieren?

Sollten wir das in diesem Thread diskutieren oder einen neuen Thread erstellen, um es zu diskutieren?

Ich würde das aufteilen. Mein unmittelbares Gefühl ist, dass das Problem darin besteht, dass --no-binary :all: hier erhebliche unbeabsichtigte Konsequenzen hat (ähnlich wie in der Praxis, wenn diese Flagge in Gegenwart eines Projekts verwendet wird, das nur Räder verteilt, keine Sdisten), und ich möchte um Abweichungen von (zum Beispiel) der Zweckmäßigkeit der Verwendung von --no-binary :all: zu vermeiden, die weiter von diesem Thread ablenkt.

Ich denke nicht , dass die Behebung des Problems mit --no-binary :all: Build-Backends annähernd so kritisch ist wie dieses. Wenn ein Benutzer bereits --no-binary :all: angibt, kann er relativ einfach --no-use-pep517 hinzufügen.

Neue PR # 6229, die:

  1. Implementiert die von @pganssle vorgeschlagene vorläufige build-system -Abschnitt in pyproject.toml zur anfänglichen Voraussetzung für die automatische Anmeldung bei PEP 517 zu machen (wobei die Option "beliebige pyproject.toml -Datei" verschoben wird). in einer späteren Version)
  2. Fügt 3 dedizierte Testfälle hinzu, die das Importieren eines benachbarten Pakets von setup.py abdecken

Ich werde die anderen 2 PRs zugunsten dieser schließen, da dies die minimale Korrektur ist, die die Dinge für Endbenutzer wieder zum Laufen bringen sollte und keine schrecklichen Hacks wie # 6210 oder eine neue Setuptools-Version wie # 6212 erfordert

Wo bleibt also setuptools.build_meta_legacy ? Soll der Vorschlag jetzt Projekte erfordern, die die Funktion "benachbartes Paket importieren" benötigen, um es explizit in pyproject.toml anzugeben? Wenn ja, würde ich dringend empfehlen, dass irgendwo dokumentiert werden muss, zusammen mit der Tatsache, dass das Importieren benachbarter Pakete ohne diese Spezifikation veraltet ist und in Pip 19.X entfernt wird (wir müssen uns einig sein, was X ist). Wir können das nicht machen eine programmatische Abwertung (glaube ich nicht), aber das ist umso mehr ein Grund, sie klar zu dokumentieren, damit wir nicht (erneut) beschuldigt werden, Funktionen ohne ausreichende Ankündigung zu entfernen.

Edit: Aber sonst danke für die neue PR und Zusammenfassung.

Bearbeiten 2: Ich sehe, Sie haben den setuptools.build_meta_legacy -Vorschlag geschlossen. Ich bin mir nicht sicher, ob mir das gefällt, da wir dadurch die Gelegenheit verlieren, jetzt zu sagen, was unser längerfristiger Plan ist, und so die oben erwähnte Abschreibungsfrist verlängern ...

@pfmoore Nein, dies bedeutet, dass die Rückkehr zum gewünschten Verhalten durch ein neues Problem abgedeckt werden sollte, das mit dem Entfernen der Problemumgehung # 6163 verbunden ist (wahrscheinlich durch Aktualisieren auf setuptools , das setuptools.build_meta_legacy bereitstellt).

Bearbeiten: Im Moment habe ich gerade # 6212 wieder geöffnet, es aber umbenannt, um zu verdeutlichen, dass ich nicht denke, dass wir warten sollten, bis die gesamte build_meta_legacy -Diskussion gelöst ist, bevor wir derzeit fehlgeschlagene Installationsbefehle korrigieren.

Mein Vorschlag war eigentlich, dass das Opt-In für PEP 517 build-system.build-backend angibt, überhaupt nicht die Existenz von build-system , und dass bis zur Veröffentlichung von 19.1 setuptools hinzugefügt werden würde build_meta_legacy und pip würden es als Standard-Backend verwenden.

Ich bin damit einverstanden, dass in 19.1 wahrscheinlich, wenn pip setuptools.build_meta_legacy nicht finden kann, es auf den alten Codepfad zurückgreifen sollte. Das gibt uns minimale Änderungen, während wir uns für die maximale Anzahl von Personen entscheiden.

Mein Vorschlag war eigentlich, dass das Opt-In für PEP 517 build-system.build-backend angibt

... was durch einfaches Setzen von use_pep517 = False im Fallback-Fall behandelt werden kann (anstatt es auf has_pyproject , was wir jetzt tun.

Wenn Pip in 19.1 setuptools.build_meta_legacy nicht finden kann, sollte es wahrscheinlich auf den alten Codepfad zurückgreifen

Ich denke nicht, dass es sich lohnt, dies zu tun. Wir werden eine ausreichend aktuelle Setuptools-Version angeben, damit wir sicher sind, dass wir das Legacy-Backend erhalten, und es besteht keine Notwendigkeit, die Möglichkeit zu berücksichtigen, dass Setuptools dieses Backend in einer zukünftigen Version entfernen (oder besser gesagt, wenn dies der Fall ist) beschuldige sie einfach für die daraus resultierenden Probleme ;-))

Hinweis: Mit der Standardeinstellung use_pep517 = False # 6229 begonnen, es wurden jedoch Fehler in den PEP 518-Tests verursacht.

  1. Der Fall " build-system.requires ist festgelegt" muss die Build-Isolation verwenden, damit die angeforderten Abhängigkeiten installiert werden können, ohne die übergeordnete Umgebung zu beeinträchtigen. Der einfachste Weg, dies angesichts der aktuellen Codestruktur zu tun, besteht darin, in diesem Fall use_pep517 = True festzulegen, also habe ich das getan und den Testfall erneut bestanden.
  2. Eine fehlende [build-system] -Tabelle zeigt an, dass pyproject.toml nur zum Speichern von Einstellungen in der [tools] -Tabelle verwendet wird. Dies use_pep517 = False , um eine effektive Problemumgehung zu sein Für das ursprünglich gemeldete Problem habe ich diesen Testfall als erwarteten Fehler markiert.
  3. Damit bleibt der Fall "leere [build-system] Tabelle", der meiner Meinung nach in beide Richtungen vernünftigerweise gelöst werden kann. Da ich jedoch nicht denke, dass dieser spezielle Fall in der Praxis sehr häufig auftreten wird (warum sollte sich jemand die Mühe machen, eine build-system -Tabelle hinzuzufügen, ohne entweder requires oder build-backend ?), Ich habe mich dafür entschieden, das Problem so zu lösen, dass der zuvor definierte PEP 518-Testfall bestanden wurde, anstatt einen zweiten erwarteten Fehlermarker hinzuzufügen.

Um 3 in die andere Richtung aufzulösen, müssten wir die Zeile ändern:

use_pep517 = build_system is not None

stattdessen sein:

use_pep517 = build_system is not None and build_system.get('requires', None)

Auf diese Weise würde sich nur eine nicht leere Anforderung für die PEP 517-Build-Isolation entscheiden (was auch das Hinzufügen eines vierten Testfalls bedeuten würde, da sich leere und nicht leere build-system.requires -Felder jetzt unterschiedlich verhalten würden).

Entschuldigen Sie den ungebetenen Beitrag hier, aber ich kann nicht anders, als zu bemerken, dass dies alles eine ziemlich aufwändige Methode ist, um zu vermeiden, dass der cwd auf sys.path und letztendlich Dinge kaputt macht, die früher funktionierten, was sich ziemlich störend anfühlt aus einer UX-Perspektive.

Eine nicht triviale Anzahl von Benutzern und Paketen ist davon betroffen. Zumindest einige von diesen haben einen Abschnitt [build-system] definiert und _auch_ verlassen sich auf das alte Verhalten und bleiben daher für jeden kaputt, der diese Versionen angeheftet hat.

@techalchemy Ja, die ursprüngliche Annahme in pip war, dass setuptools.build_meta der Perspektive von sys.path genauso funktioniert wie der direkte Aufruf von setup.py , und diese Annahme erwies sich als falsch. Sobald eine Veröffentlichung von setuptools mit dem in https://github.com/pypa/setuptools/pull/1652 definierten setuptools.build_meta_legacy Backend verfügbar ist, kann # 6212 abgeschlossen werden, und das wäre die lange Zeit Laufzeitauflösung. Es gibt jedoch keine aktuelle ETA für eine solche Version. Daher müssen wir weiterhin nur pip -Auflösungen untersuchen, um das Quellverzeichnis für Pakete, die nicht explizit "PEP 517 native" sind, wieder auf sys.path zu bringen ".

In # 6229 habe ich den Vorschlag von @pganssle implementiert, die Einführung von "PEP 517 standardmäßig" einfach zu verschieben, aber es sieht so aus, als würde dies aufgrund einer weiteren Änderung von pip 19 mehr Probleme verursachen als lösen: die Verarbeitung von build-system.requires ist jetzt an die Verarbeitung von build-system.build-backend gebunden, daher deaktiviert --no-use-pep517 PEP 518 (was zu Fehlern in der Testsuite führt und bei der Erstellung auch zu Installationsfehlern in der realen Welt führen kann Abhängigkeiten sind nicht vorinstalliert).

In # 6210 patche ich stattdessen pep517 lokal, um das Injizieren von sys.path[0] in den Unterprozess zu unterstützen, und mache effektiv das Gleiche, was setuptools.build_meta_legacy in einem zukünftigen setutpools tun wird build-system.requires wird noch verarbeitet, und das Quellverzeichnis ist sys.path[0] wenn setup.py ausgeführt wird. Es ist auch sehr ähnlich zu dem, was ich in vorgeschlagenen https://discuss.python.org/t/pep-517-backend-bootstrapping/789/29?u=ncoghlan und @takluyver hat in entworfen https://github.com/ pypa / pep517 / pull / 42 / , um Self-Bootstrapping-Backends so zu handhaben, dass sie mit --no-binary :all: kompatibel sind

Tut mir leid, dass ich der AWOL RM bin. Es passierten Dinge, mit denen ich nicht gerechnet hatte.

Ich bevorzuge natürlich das Setuptools-seitige Update dafür, aber # 6210 ist auch bei mir cool - als kurzfristiges Update.

Ich stimme @techalchemy und @pradyunsg zu - ich denke, der setuptools-seitige Fix ist hier der richtige Ansatz. Obwohl ich die Arbeit an dem Versuch, eine schnelle Lösung in pip zu finden, sehr schätze, wäre es nicht besser, diese Zeit damit zu verbringen, eine neue Version von Setuptools mit _build_meta_legacy beschleunigen? Ich habe nicht beobachtet, was auf Setuptools passiert, daher ist mir überhaupt nicht klar, warum es ein Problem gibt, eine schnelle Lösung in Setuptools freizugeben (die Release-Zyklen von Setuptools sind viel schneller als die von Pip).

Ich bin mit einem kurzfristigen Pip-Side-Fix einverstanden, aber ich möchte klarstellen, wann wir mit einem Setuptools-Fix rechnen können.

Hallo zusammen!

Ich habe das gleiche Problem:

**Collecting pyinstaller==3.4
  Using cached https://files.pythonhosted.org/packages/
a0cc/PyInstaller-3.4.tar.gz
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  Complete output from command "c:\program files (x86)\
gram files (x86)\microsoft visual studio\shared\python3
requires_for_build_wheel C:\Users\ASUS\AppData\Local\Te
  Traceback (most recent call last):
    File "c:\program files (x86)\microsoft visual studi
process.py", line 207, in <module>
      main()
    File "c:\program files (x86)\microsoft visual studi
process.py", line 197, in main
      json_out['return_val'] = hook(**hook_input['kwarg
    File "c:\program files (x86)\microsoft visual studi
process.py", line 54, in get_requires_for_build_wheel
      return hook(config_settings)
    File "C:\Users\ASUS\AppData\Local\Temp\pip-build-en
, line 115, in get_requires_for_build_wheel
      return _get_build_requires(config_settings, requi
    File "C:\Users\ASUS\AppData\Local\Temp\pip-build-en
, line 101, in _get_build_requires
      _run_setup()
    File "C:\Users\ASUS\AppData\Local\Temp\pip-build-en
, line 85, in _run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 20, in <module>
      from PyInstaller import __version__ as version, H
  ModuleNotFoundError: No module named 'PyInstaller'**

Weiß jemand, ob das Problem gelöst ist? Oder wie kann man es vorübergehend lösen?

Vielen Dank an alle!

@ jce94 , benutze jetzt pip <19.

@altendky danke für die Info!

Ich konnte dieses Problem mit den vorgeschlagenen Problemumgehungen nicht lösen, während ich mit pipenv . Das Einfrieren von pip auf 18.1 in Pipfile scheint keine Auswirkung zu haben, da pipenv weiterhin die neueste Pip-Version erzwingen. Ich kann pip manuell auf 18.1 einstellen, aber wenn ich die virtuelle Umgebung von pipenv neu erstelle, würde Pipenv auf die neueste pip aktualisieren, egal was passiert ... Irgendwelche Empfehlungen, damit es bleibt?

@altendky Leider ist die Verwendung einer vordefinierten Version von pip derzeit für Benutzer von pipenv (und auch für Gedichte, glaube ich) nicht möglich. Beide verwenden die neuesten Versionen. Ich vermute also, dass viele Leute vorerst mit kaputten Pipelines festsitzen

Was noch seltsamer ist, es passiert nicht konsequent. Ich habe einen Appveyor-Job erneut ausgeführt, der erste ist bestanden, der zweite ist fehlgeschlagen, obwohl sie streng identisch sind

Für den Fall, dass sich jemand über die Zeitachse wundert, werden wir voraussichtlich Ende dieser Woche oder Anfang nächster Woche einen Fix fertig haben und bald darauf eine nachfolgende Bugfix-Version von pip veröffentlichen können.

Die neue Version von setuptools, Version 40.8.0 ist jetzt mit dem Backend build_meta:__legacy__ verfügbar.

Vielen Dank! Und sollten wir PyInstaller darauf hinweisen? Sie sind
ziemlich unzufrieden mit den Änderungen ... Jede Dokumentation oder PEP, die ich präsentieren kann
sie mit, um die Änderungen zu unterstützen?

Am Dienstag, 5. Februar 2019, 10:24 Uhr schrieb Paul Ganssle < [email protected] :

Die neue Version von setuptools, Version 40.8.0, ist jetzt mit dem verfügbar
build_meta: __ Legacy__ Backend.

- -
Sie erhalten dies, weil Sie kommentiert haben.
Antworte direkt auf diese E-Mail und sieh sie dir auf GitHub an
https://github.com/pypa/pip/issues/6163#issuecomment-460747909 oder stumm schalten
der Faden
https://github.com/notifications/unsubscribe-auth/ADtXZjnOfu56IYR6VEKK4yowMg3XdcFEks5vKcxBgaJpZM4aNvmP
.

@AlmogCohen Nein, dies sollten Sie nicht direkt verwenden, sondern nur für PEP 517-Frontends. Der nächste Schritt besteht darin, dass pip build_meta:__legacy__ als Standard-Backend verwendet. Dies ist aus Sicht des Endbenutzers nicht umsetzbar.

Gibt es eine ETA für die neue Version, die das Update integriert?

In wenigen Stunden. :) :)

Siehe das angeheftete Problem.

pip 19.0.2 wurde mit einem Fix dafür veröffentlicht.

Ich kann pyinstaller mit der neuesten Version von pip installieren, selbst wenn ich --no-use-pep517

pip install pyinstaller --no-cache-dir --no-use-pep517
Collecting pyinstaller
  Downloading https://files.pythonhosted.org/packages/03/32/0e0de593f129bf1d1e77eed562496d154ef4460fd5cecfd78612ef39a0cc/PyInstaller-3.4.tar.gz (3.5MB)
     |████████████████████████████████| 3.5MB 273kB/s
  Installing build dependencies ... done
    ERROR: Complete output from command python setup.py egg_info:
    ERROR: Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\Raffaele\AppData\Local\Temp\pip-install-5e9w2p2c\pyinstaller\setup.py", line 20, in <module>
        from PyInstaller import __version__ as version, HOMEPATH, PLATFORM
    ModuleNotFoundError: No module named 'PyInstaller'
    ----------------------------------------
ERROR: Command "python setup.py egg_info" failed with error code 1 in C:\Users\Raffaele\AppData\Local\Temp\pip-install-5e9w2p2c\pyinstaller\

Dieser Thread wurde automatisch gesperrt, da nach dem Schließen keine aktuellen Aktivitäten stattgefunden haben. Bitte öffnen Sie eine neue Ausgabe für verwandte Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen