Werkzeug: Reloader, Python -m und sys.path

Erstellt am 11. Nov. 2013  ·  12Kommentare  ·  Quelle: pallets/werkzeug

Siehe https://github.com/Kozea/WeasyPrint/issues/133

Was ist los ist:

  • python -m weasyprint.navigator wird ausgeführt
  • [sys.executable] + sys.argv ist ['…/python', '…/weasyprint/navigator.py']
  • Der Reloader erzeugt auf diese Weise einen Unterprozess
  • Der untergeordnete Prozess hat nicht -m , daher fügt Python das übergeordnete Verzeichnis der .py-Datei zu sys.path
  • Werkzeug versucht, stdlibs html.entities zu importieren
  • Dies importiert fälschlicherweise weasyprint/html.py
  • Sachen brechen

Niemand hier macht offensichtlich etwas falsch. Wie schlagen Sie vor, mit dieser Situation umzugehen? Was halten Sie davon, dass …/weasyprint/navigator.py (das voraussichtlich hauptsächlich mit python -m ) sein übergeordnetes Verzeichnis aus sys.path wenn es dort ist?

bug reloader

Hilfreichster Kommentar

Ich habe ein ähnliches Problem, bei dem relative Importe fehlschlagen, weil der Reloader das Modul als Nicht-Paket ausführt:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Anhand der Kommentare von @untitaker können wir in Python <3.3 erkennen, ob python -m verwendet wurde (nur dann ist __loader__ definiert), und den Reloader zwingen, es auch zu verwenden, indem wir sys.argv zurücksetzen

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Dies ist jedoch eine ziemlich umständliche Problemumgehung (und nur für Python <3.3).

Die aktuelle Implementierung in # 531 behebt dieses spezielle Problem nicht und ich sehe leider keine Möglichkeit, wie es könnte.

Alle 12 Kommentare

Ich glaube nicht, dass es nicht schaden würde, wenn Werkzeug den Unterprozess mit denselben Argumenten erzeugen würde, wobei __loader__.fullname in Python 2 und __loader__.name in Python 3 verwendet würden, falls vorhanden.

@untitaker , ich verstehe nicht was du meinst. Was ist __loader__ ?

Können wir in Python erkennen, ob python -m somemodule verwendet wurde oder nicht?

Ich bin auf eine StackOverflow-Antwort gestoßen, in der erklärt wurde, wie der aktuelle Modulname abgerufen wird. Ein einfacher Test zeigt, dass in Python 2 __loader__.fullname verfügbar ist:

print(__loader__.fullname)

Das __loader__ global existiert nicht, wenn die Python-Datei ohne -m , und es existiert auch nicht in importierten Modulen.

In Python 3, die beide das Modul mit ausgeführt -m und alle andere importierten Module scheinen haben __loader__ global, das fullname Attribut ist jetzt name . In jedem Modul hat das Attribut name den Wert des Moduls _current_.

In Python 2 können wir also feststellen, ob wir mit -m , aber nicht mit 3.

Auch die Erkennung ist sehr begrenzt, sodass Sie innerhalb des direkt ausgeführten Moduls nur erkennen können, ob python -m verwendet wurde, indem Sie nach der Variablen __loader__ suchen. Außerdem scheint dieses Verhalten nur spärlich dokumentiert zu sein, daher bin ich mir nicht sicher, ob wir das sowieso in Werkzeug wollen.

Ich bin gerade selbst auf diesen Fehler gestoßen. Ich habe erwartet, dass die Flagge -m in sys.argv , aber das ist es definitiv nicht.

Gibt es dafür eine Problemumgehung?

Ja, eine davon finden Sie unter https://github.com/mitsuhiko/flask/issues/1246

Am 9. Juli 2015 um 15:08:30 Uhr MESZ schrieb Wayne Werner [email protected] :

Ich bin gerade selbst auf diesen Fehler gestoßen. Ich habe erwartet, dass die Flagge -m sein wird
vorhanden in sys.argv , aber es ist definitiv nicht.

Gibt es dafür eine Problemumgehung?


Antworte direkt auf diese E-Mail oder sieh sie dir auf GitHub an:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -119955695

Von meinem Android-Gerät mit K-9 Mail gesendet. Bitte entschuldigen Sie meine Kürze.

Ich habe ein ähnliches Problem, bei dem relative Importe fehlschlagen, weil der Reloader das Modul als Nicht-Paket ausführt:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Anhand der Kommentare von @untitaker können wir in Python <3.3 erkennen, ob python -m verwendet wurde (nur dann ist __loader__ definiert), und den Reloader zwingen, es auch zu verwenden, indem wir sys.argv zurücksetzen

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Dies ist jedoch eine ziemlich umständliche Problemumgehung (und nur für Python <3.3).

Die aktuelle Implementierung in # 531 behebt dieses spezielle Problem nicht und ich sehe leider keine Möglichkeit, wie es könnte.

Ich glaube, ich habe einmal versucht, dies mit dem Lader zu beheben, aber es hat sich sehr gut gezeigt
unterschiedliches Verhalten von 2 bis 3.

Am Do, 10. September 2015 um 13:26:56 Uhr -0700 schrieb Martijn Vermaat:

Ich habe ein ähnliches Problem, bei dem relative Importe fehlschlagen, weil der Reloader das Modul als Nicht-Paket ausführt:

$ python -m myapp.entrypoints.website
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
Traceback (most recent call last):
  File "/tmp/myapp/entrypoints/website.py", line 9, in <module>
    from . import mymodule
ValueError: Attempted relative import in non-package

Anhand der Kommentare von @untitaker können wir in Python <3.3 erkennen, ob python -m verwendet wurde (nur dann ist __loader__ definiert), und den Reloader zwingen, es auch zu verwenden, indem wir sys.argv zurücksetzen

try:
    sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
    pass

Dies ist jedoch eine ziemlich umständliche Problemumgehung (und nur für Python <3.3).


Antworte direkt auf diese E-Mail oder sieh sie dir auf GitHub an:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -139369694

Traurig,

$ python -m werkzeug.serving weasyprint. Navigator: app --reload --debug

  • Läuft unter http://127.0.0.1 : 5000 / (Drücken Sie STRG + C, um das Programm zu beenden.)
  • Neustart mit stat
    Traceback (letzter Anruf zuletzt):
    Datei "/usr/lib/python2.7/site-packages/werkzeug/serving.py", Zeile 45, in
    aus ._compat importiere PY2
    ValueError: Relativer Importversuch in Nicht-Paket versucht

Dieser Python-Fehler kann mit Python nicht ordnungsgemäß behoben werden. Ich empfehle daher, ein Konsolenskript bereitzustellen

Irgendwelche Änderungen daran? Ich bin gerade python -m werkzeug.serving app:application dieses Problem gestoßen ... (Python 3.6, kein Weasyprint, nur

Ich habe es geschafft, das Problem zu umgehen, indem ich etwas getan habe wie:

PYTHONPATH=$PWD:$PYTHONPATH python -m myapp.entrypoints.website

_Edit: erkannte, dass die Lösung direkt über war : arrow_up: _

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen