Voir https://github.com/Kozea/WeasyPrint/issues/133
Ce qui se passe, c'est:
python -m weasyprint.navigator
est exécuté[sys.executable] + sys.argv
est ['…/python', '…/weasyprint/navigator.py']
-m
, donc Python ajoute le répertoire parent du fichier .py à sys.path
html.entities
stdlibweasyprint/html.py
Personne ici ne fait manifestement rien de mal. Comment proposez-vous de gérer cette situation? Que pensez-vous du fait que …/weasyprint/navigator.py
(qui devrait être principalement utilisé avec python -m
) supprime son répertoire parent de sys.path
s'il y est?
Je ne pense pas que cela ne ferait pas de mal si Werkzeug engendrait le sous-processus avec en fait les mêmes arguments, en utilisant __loader__.fullname
en Python 2 et __loader__.name
en Python 3 s'il existe.
@untitaker , je ne comprends pas ce que vous voulez dire. Qu'est-ce que __loader__
?
Peut-on détecter en Python si python -m somemodule
été utilisé ou non?
Je suis tombé sur une réponse StackOverflow qui expliquait comment obtenir le nom du module actuel. Un test simple montre qu'en Python 2, __loader__.fullname
est disponible:
print(__loader__.fullname)
Le __loader__
global n'existe pas si le fichier Python est exécuté sans -m
, et il n'existe pas non plus dans les modules importés.
Dans Python 3, le module exécuté avec -m
et tous les autres modules importés semblent avoir un __loader__
global, l'attribut fullname
est maintenant name
. Mais à l'intérieur de chaque module, l'attribut name
a la valeur du module _current_.
Ainsi, dans Python 2, nous _pouvons_ détecter si nous fonctionnons avec -m
, mais pas avec 3.
De plus, la détection est très limitée non plus, donc vous ne pouvez détecter à l'intérieur du module exécuté directement que si python -m
été utilisé en vérifiant la variable __loader__
. De plus, ce comportement semble peu documenté, donc je ne suis pas sûr que ce soit ce que nous voulons de toute façon dans Werkzeug.
Je viens de tomber sur ce bug moi-même. Je m'attendais à ce que le drapeau -m
soit présent dans sys.argv
, mais ce n'est certainement pas le cas.
Existe-t-il une solution de contournement pour cela?
Oui, un est présenté sur https://github.com/mitsuhiko/flask/issues/1246
Le 9 juillet 2015 à 15:08:30 CEST, Wayne Werner [email protected] a écrit:
Je viens de tomber sur ce bug moi-même. Je m'attendais à ce que l'indicateur
-m
soit
présent danssys.argv
, mais ce n'est certainement pas le cas.Existe-t-il une solution de contournement pour cela?
Répondez directement à cet e-mail ou affichez-le sur GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -119955695
Envoyé depuis mon appareil Android avec K-9 Mail. Veuillez excuser ma brièveté.
J'ai un problème similaire, où les importations relatives échouent car le rechargeur exécute le module en tant que non-package:
$ 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
En utilisant les commentaires de @untitaker , en Python <3.3, nous pouvons détecter si python -m
été utilisé (alors seulement __loader__
défini) et forcer le rechargeur à l'utiliser également en réinitialisant sys.argv
:
try:
sys.argv = ['-m', __loader__.fullname] + sys.argv[1:]
except NameError:
pass
Mais c'est une solution de contournement assez piratée (et uniquement pour Python <3.3).
L'implémentation actuelle dans # 531 ne résout pas ce problème particulier et je ne vois malheureusement pas comment cela pourrait.
Je pense que j'ai essayé de résoudre ce problème avec le chargeur une fois, mais cela a montré énormément
comportement différent de 2 à 3.
Le jeu.10 septembre 2015 à 13:26:56 -0700, Martijn Vermaat a écrit:
J'ai un problème similaire, où les importations relatives échouent car le rechargeur exécute le module en tant que non-package:
$ 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
En utilisant les commentaires de @untitaker , en Python <3.3, nous pouvons détecter si
python -m
été utilisé (alors seulement__loader__
défini) et forcer le rechargeur à l'utiliser également en réinitialisantsys.argv
:try: sys.argv = ['-m', __loader__.fullname] + sys.argv[1:] except NameError: pass
Mais c'est une solution de contournement assez piratée (et uniquement pour Python <3.3).
Répondez directement à cet e-mail ou affichez-le sur GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -139369694
Malheureusement,
$ python -m werkzeug.serving weasyprint. navigateur: app --reload --debug
Ce bogue de python ne peut pas être corrigé correctement avec python, je suggère donc de fournir un script de console
Y a-t-il un changement à cela? Je viens de rencontrer ce problème ... (Python 3.6, pas de weasyprint, juste python -m werkzeug.serving app:application
)
J'ai réussi à contourner le problème en faisant quelque chose comme:
PYTHONPATH=$PWD:$PYTHONPATH python -m myapp.entrypoints.website
_Edit: réalisé que la solution était juste au-dessus : arrow_up: _
Commentaire le plus utile
J'ai un problème similaire, où les importations relatives échouent car le rechargeur exécute le module en tant que non-package:
En utilisant les commentaires de @untitaker , en Python <3.3, nous pouvons détecter si
python -m
été utilisé (alors seulement__loader__
défini) et forcer le rechargeur à l'utiliser également en réinitialisantsys.argv
:Mais c'est une solution de contournement assez piratée (et uniquement pour Python <3.3).
L'implémentation actuelle dans # 531 ne résout pas ce problème particulier et je ne vois malheureusement pas comment cela pourrait.