Werkzeug: Reloader, python -m y sys.path

Creado en 11 nov. 2013  ·  12Comentarios  ·  Fuente: pallets/werkzeug

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

Lo que esta pasando es:

  • python -m weasyprint.navigator se ejecuta
  • [sys.executable] + sys.argv es ['…/python', '…/weasyprint/navigator.py']
  • El cargador genera un subproceso de esa manera
  • El proceso hijo no tiene -m , por lo que Python agrega el directorio principal del archivo .py a sys.path
  • Werkzeug intenta importar stdlib's html.entities
  • Esto importa incorrectamente weasyprint/html.py
  • Las cosas se rompen

Nadie aquí está haciendo nada obviamente mal. ¿Cómo sugieres lidiar con esta situación? ¿Qué piensas de que …/weasyprint/navigator.py (que se espera que se use principalmente con python -m ) elimine su directorio principal de sys.path si está allí?

bug reloader

Comentario más útil

Tengo un problema similar, donde las importaciones relativas fallan porque el cargador ejecuta el módulo como un no paquete:

$ 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

Usando los comentarios de @untitaker , en Python <3.3 podemos detectar si se usó python -m (solo entonces se define __loader__ ) y forzar al recargador a usarlo también reiniciando sys.argv :

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

Pero esta es una solución bastante complicada (y solo para Python <3.3).

La implementación actual en el n. ° 531 no soluciona este problema en particular y, desafortunadamente, no veo cómo podría hacerlo.

Todos 12 comentarios

No creo que no estaría mal si Werkzeug generó el subproceso con los mismos argumentos, usando __loader__.fullname en Python 2 y __loader__.name en Python 3 si existe.

@untitaker , no entiendo a qué te refieres. ¿Qué es __loader__ ?

¿Podemos detectar en Python si se usó python -m somemodule o no?

Encontré una respuesta de StackOverflow que explicaba cómo obtener el nombre del módulo actual. Una prueba simple muestra que en Python 2, __loader__.fullname está disponible:

print(__loader__.fullname)

El __loader__ global no existe si el archivo Python se ejecuta sin -m , y tampoco existe en los módulos importados.

En Python 3, tanto el módulo ejecutado con -m como cualquier otro módulo importado parecen tener un __loader__ global, el atributo fullname ahora es name . Pero dentro de cada módulo, el atributo name tiene el valor del módulo _current_.

Entonces, en Python 2 _can_detectamos si estamos ejecutando con -m , pero no en 3.

Además, la detección es muy limitada, por lo que solo puede detectar dentro del módulo ejecutado directamente si se usó python -m al verificar la variable __loader__ . Además, este comportamiento parece escasamente documentado, por lo que no estoy seguro de si eso es lo que queremos en Werkzeug de todos modos.

Yo mismo me encontré con este error. Esperaba que la bandera -m estuviera presente en sys.argv , pero definitivamente no lo está.

¿Existe algún tipo de solución para esto?

Sí, uno se presenta en https://github.com/mitsuhiko/flask/issues/1246

El 9 de julio de 2015 a las 15:08:30 CEST, Wayne Werner [email protected] escribió:

Yo mismo me encontré con este error. Esperaba que la bandera -m fuera
presente en sys.argv , pero definitivamente no lo es.

¿Existe algún tipo de solución para esto?


Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -119955695

Enviado desde mi dispositivo Android con K-9 Mail. Por favor, disculpe mi brevedad.

Tengo un problema similar, donde las importaciones relativas fallan porque el cargador ejecuta el módulo como un no paquete:

$ 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

Usando los comentarios de @untitaker , en Python <3.3 podemos detectar si se usó python -m (solo entonces se define __loader__ ) y forzar al recargador a usarlo también reiniciando sys.argv :

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

Pero esta es una solución bastante complicada (y solo para Python <3.3).

La implementación actual en el n. ° 531 no soluciona este problema en particular y, desafortunadamente, no veo cómo podría hacerlo.

Creo que traté de arreglar esto con el cargador una vez, pero se mostró enormemente
comportamiento diferente de 2 a 3.

El jueves, 10 de septiembre de 2015 a las 01:26:56 PM -0700, Martijn Vermaat escribió:

Tengo un problema similar, donde las importaciones relativas fallan porque el cargador ejecuta el módulo como un no paquete:

$ 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

Usando los comentarios de @untitaker , en Python <3.3 podemos detectar si se usó python -m (solo entonces se define __loader__ ) y forzar al recargador a usarlo también reiniciando sys.argv :

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

Pero esta es una solución bastante complicada (y solo para Python <3.3).


Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -139369694

Desafortunadamente,

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

  • Ejecutando en http://127.0.0.1 : 5000 / (Presione CTRL + C para salir)
  • Reiniciando con stat
    Rastreo (llamadas recientes más última):
    Archivo "/usr/lib/python2.7/site-packages/werkzeug/serving.py", línea 45, en
    desde ._compat import PY2
    ValueError: Intento de importación relativa en un no paquete

Este error de Python no se puede solucionar correctamente con Python, por lo que sugiero proporcionar un script de consola

¿Algún cambio en esto? Me encontré con este problema ... (Python 3.6, sin weasyprint, solo python -m werkzeug.serving app:application )

Me las arreglé para solucionar el problema haciendo algo como:

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

_Editar: me di cuenta de que la solución estaba justo arriba : arrow_up: _

¿Fue útil esta página
0 / 5 - 0 calificaciones