Werkzeug: 重新加载器,python -m和sys.path

创建于 2013-11-11  ·  12评论  ·  资料来源: pallets/werkzeug

参见https://github.com/Kozea/WeasyPrint/issues/133

发生了什么事:

  • python -m weasyprint.navigator正在运行
  • [sys.executable] + sys.argv['…/python', '…/weasyprint/navigator.py']
  • 重新加载器以这种方式产生一个子进程
  • 子进程没有-m ,因此Python将.py文件的父目录添加到sys.path
  • Werkzeug尝试导入stdlib的html.entities
  • 这会错误地导入weasyprint/html.py
  • 休息时间

这里没有人做任何明显错误的事情。 您如何建议应对这种情况? 您如何看待…/weasyprint/navigator.py (通常将与python -m )从sys.path删除其父目录(如果有)?

bug reloader

最有用的评论

我有一个类似的问题,其中相对导入失败,因为重新加载程序将模块作为非软件包执行:

$ 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

使用@untitaker的注释,在Python <3.3中,我们可以检测是否使用了python -m (只有然后定义了__loader__ ),并通过重置sys.argv来强制重新加载器也使用它

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

但这是一个很棘手的解决方法(仅适用于<3.3的Python)。

#531中的当前实现无法解决此特定问题,不幸的是,我看不到任何解决方法。

所有12条评论

我认为,如果Werkzeug使用实际上相同的参数生成子进程也不会有害,在Python 2中使用__loader__.fullname在Python 3中使用__loader__.name (如果存在)。

@untitaker ,我不明白你的意思。 什么是__loader__

我们是否可以在Python中检测是否使用了python -m somemodule

我浏览了一个StackOverflow答案,该__loader__.fullname可用:

print(__loader__.fullname)

如果在没有-m情况下执行Python文件,则__loader__全局不存在,并且在导入的模块中也不存在。

在Python 3中,用-m执行的模块和任何其他导入的模块似乎都具有__loader__全局变量, fullname属性现在name 。 但是在每个模块中, name属性具有_current_模块的值。

因此,在Python 2中,我们可以_can_检测是否正在使用-m ,但不能在3中运行。

此外,检测也非常有限,因此,如果通过检查__loader__变量使用了python -m则只能在直接执行的模块内部进行检测。 另外,这种行为似乎很少被记录在案,所以我不确定这是否就是我们在Werkzeug中想要的。

我自己碰到了这个错误。 我预计sys.argv会出现-m标志,但绝对没有。

有什么解决方法吗?

是的,在https://github.com/mitsuhiko/flask/issues/1246中提供了一个

2015年7月9日CEST,韦恩·沃纳(Wayne Werner) [email protected]写道:

我自己碰到了这个错误。 我期望-m标志是
存在于sys.argv ,但绝对不是。

有什么解决方法吗?


直接回复此电子邮件或在GitHub上查看:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -119955695

使用K-9 Mail从我的Android设备发送。 请原谅我。

我有一个类似的问题,其中相对导入失败,因为重新加载程序将模块作为非软件包执行:

$ 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

使用@untitaker的注释,在Python <3.3中,我们可以检测是否使用了python -m (只有然后定义了__loader__ ),并通过重置sys.argv来强制重新加载器也使用它

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

但这是一个很棘手的解决方法(仅适用于<3.3的Python)。

#531中的当前实现无法解决此特定问题,不幸的是,我看不到任何解决方法。

我想我曾经尝试用加载程序修复此问题,但它显示了很多
从2到3的不同行为。

Martijn Vermaat在2015年9月10日,星期四,00-07:01:26:56PM写道:

我有一个类似的问题,其中相对导入失败,因为重新加载程序将模块作为非软件包执行:

$ 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

使用@untitaker的注释,在Python <3.3中,我们可以检测是否使用了python -m (只有然后定义了__loader__ ),并通过重置sys.argv来强制重新加载器也使用它

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

但这是一个很棘手的解决方法(仅适用于<3.3的Python)。


直接回复此电子邮件或在GitHub上查看:
https://github.com/mitsuhiko/werkzeug/issues/461#issuecomment -139369694

可悲的是

$ python -m werkzeug.serving weasyprint。 导航器:应用程序-重新加载-调试

  • http://127.0.0.1:5000 /上运行(按CTRL + C退出)
  • 用统计重启
    追溯(最近一次通话):
    在第45行的“ /usr/lib/python2.7/site-packages/werkzeug/serving.py”文件中
    从._compat导入PY2
    ValueError:尝试在非包中进行相对导入

无法使用python正确修复python的这个错误,因此我建议提供一个控制台脚本

这有什么变化吗? 刚遇到这个问题...(Python 3.6,没有weasyprint,只有python -m werkzeug.serving app:application

我设法通过以下方法解决了这个问题:

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

_编辑:意识到解决方案就在:arrow_up:_

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

asottile picture asottile  ·  11评论

d42 picture d42  ·  6评论

KangOl picture KangOl  ·  16评论

mhelmetag picture mhelmetag  ·  8评论

mrx23dot picture mrx23dot  ·  6评论