尽管软件包安装在 virtualenv 中并且在 Google Cloud SDK 中可用,但 Google AppEngine dev_appserver 引发 ImportError

Posted

技术标签:

【中文标题】尽管软件包安装在 virtualenv 中并且在 Google Cloud SDK 中可用,但 Google AppEngine dev_appserver 引发 ImportError【英文标题】:Google AppEngine dev_appserver raises ImportError despite package being installed in virtualenv and available in Google Cloud SDK 【发布时间】:2021-08-03 19:42:54 【问题描述】:

我正在开发一个使用旧版 Python 2.7 运行时的 Google AppEngine 项目 - 我的团队正在从该项目中迁移出去,但我们目前仍在使用它。在过去的大约 6 个月里,本地开发对我来说运行良好,我的团队中没有其他人受到以下问题的影响。

在启动 dev_appserver.py 时以及在处理任何请求期间,我都会收到 ImportError

09:36:59 dev_server.1    | ERROR    2021-05-13 13:36:59,470 wsgi.py:269] 
09:36:59 dev_server.1    | Traceback (most recent call last):
09:36:59 dev_server.1    |   File "/Users/me/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
09:36:59 dev_server.1    |     handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
09:36:59 dev_server.1    |   File "/Users/me/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 311, in _LoadHandler
09:36:59 dev_server.1    |     handler, path, err = LoadObject(self._handler)
09:36:59 dev_server.1    |   File "/Users/me/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
09:36:59 dev_server.1    |     obj = __import__(path[0])
09:36:59 dev_server.1    |   File "/Users/me/Source/myproject/main.py", line 5, in <module>
09:36:59 dev_server.1    |     import webapp2
09:36:59 dev_server.1    |   File "/Users/me/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 25, in <module>
09:36:59 dev_server.1    |     import webob
09:36:59 dev_server.1    |   File "/private/var/folders/qs/2qn9hbhn3k77wbhgsg77w6tm0000gn/T/pip-target-etkWjd/lib/python/webob/__init__.py", line 1, in <module>
09:36:59 dev_server.1    |   File "/Users/me/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/python/runtime/sandbox.py", line 1168, in load_module
09:36:59 dev_server.1    |     raise ImportError('No module named %s' % fullname)
09:36:59 dev_server.1    | ImportError: No module named webob.datetime_utils

如您所见,错误发生在导入webapp2 时,它调用import webobwebob 都安装在我的 virtualenv 中:

(myenv) me@pegasus site % pip list | grep WebOb
WebOb                         1.8.7

以及app.yaml中指定的:

libraries:
...
- name: webob
  version: "1.2.3"
...

我已确保我的 virtualenv 在我启动 dev_appserver.py 时处于活动状态。

让我好奇的是这行回溯:

09:36:59 dev_server.1  |  File "/private/var/folders/qs/2qn9hbhn3k77wbhgsg77w6tm0000gn/T/pip-target-etkWjd/lib/python/webob/__init__.py", line 1, in <module>

我不知道为什么要执行 /private/var/folders 中的代码 - 它不应该是调用我的 virtualenv 中的代码还是 Google Cloud SDK 提供的代码?

它似乎在 SDK 中 - 调用者是 google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py,但是我找不到任何理由说明为什么 webob 的解析路径在 /private/var/folders 中,而不是我的 virtualenv 中,或者更明智的是, webob-1.2.3 包也位于google-cloud-sdk/platform/google_appengine/lib/

事实上,在大约 6 年的全职 Python 开发中,我从未在回溯中看到过这样的文件路径——我总是希望执行的代码在我自己的文件中或关联的 virtualenv 的 site-packages 中.

此外,回溯中的文件不存在(或者至少对我不可见):尝试 ls /private/var/folders/qs/2qn9hbhn3k77wbhgsg77w6tm0000gn/T/pip-target-etkWjd/ 目录会导致 No such file or directory

我的尝试:

    完全删除并重新安装了我的 virtualenv 和 Google Cloud SDK。 删除了pip 已安装的webob 实例。 重新安装了webob 与 SDK (1.2.3) 附带的相同版本。 使用pyenv 安装了一个新的python2.7 实例,并用它来删除和重新创建我的virtualenv。 从我的PATH 中删除所有无关条目,以查看是否某些条目导致导入系统以意外方式解析 webob

这些都没有奏效。最终,我仍然不确定如果将包安装在活动的 virtualenv 中,导入将如何失败 - 我希望 Google Cloud SDK 中的 webapp2 模块可以通过 virtualenv 解决导入问题,但我我绝对不是导入系统方面的专家。

【问题讨论】:

也许尝试从您的虚拟环境中卸载 WebOb。 GAE 第一代想要使用自己的内部 WebOb,因此您的虚拟环境中存在 WebOb 可能会造成混乱。 @gaefan 感谢您的浏览!我有同样的想法,但不幸的是这并没有帮助。为了更好地衡量,我刚刚用我的新 virtualenv 再次尝试,但结果是一样的。我已经验证 SDK 文件夹中存在内部 WebOb,所以我不确定为什么在导入过程中 sandbox.py 找不到它。 【参考方案1】:

在尝试导入 webob 之前,我最终将以下代码添加到 /Users/me/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py

import imp
fp, pathname, description = imp.find_module('webob')
print '--------------------------'
print fp
print pathname
print description
print '--------------------------'

打印出来的:

14:03:13 dev_server.1    |--------------------------
14:03:13 dev_server.1    | None
14:03:13 dev_server.1    | /Users/me/Source/myproject/lib/webob
14:03:13 dev_server.1    | ('', '', 5)
14:03:13 dev_server.1    | --------------------------

lib 中的这个 webob 目录出乎意料 - 它包含在 GAE 上的 python2 运行时以及 SDK 中,因此不需要在 lib 中出售。它也是空的,所以我没有注意到它,因为git 没有报告任何新的未跟踪文件。

我不太确定机制,但这导致了导入问题 - 只要我删除了空目录,问题就解决了。

【讨论】:

以上是关于尽管软件包安装在 virtualenv 中并且在 Google Cloud SDK 中可用,但 Google AppEngine dev_appserver 引发 ImportError的主要内容,如果未能解决你的问题,请参考以下文章

macOS下Python多版本控制软件的安装:pyenvpyenv-virtualenv

错误:在 virtualenv 上安装某些软件包时出现“没有名为 _markerlib 的模块”

在 openSuSE 中使用带有 python3 的 virtualenv

Virtualenvs 中损坏的引用

无法将cvxpy安装到AWS Lambda的virtualenv中

将virtualenv从host1复制到host2,但是,host2上的virtualenv显示没有已安装的软件包