GAE Python开发服务器在升级到2.7后间歇性崩溃
我最近把我的GAE Python应用升级到了Python 2.7。从那以后,我在开发服务器上时不时会遇到以下错误,结果开发服务器只显示一个空白页面:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 168, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/runtime/wsgi.py", line 206, in _LoadHandler
handler = __import__(path[0])
[...]
File "/Users/joneill/OpenSTV/OpenSTV/trunk/OpaVote-HR/main.py", line 2, in <module>
import views
[...]
File "/Users/joneill/OpenSTV/OpenSTV/trunk/OpaVote-HR/views.py", line 3, in <module>
from pytz.gae import pytz
[...]
File "/Users/joneill/OpenSTV/OpenSTV/trunk/OpaVote-HR/pytz/__init__.py", line 34, in <module>
from pkg_resources import resource_stream
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 662, in Decorate
return func(self, *args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 1818, in load_module
return self.FindAndLoadModule(submodule, fullname, search_path)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 662, in Decorate
return func(self, *args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 1690, in FindAndLoadModule
description)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 662, in Decorate
return func(self, *args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 1615, in LoadModuleRestricted
return source_file.load_module(submodule_fullname)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist/py_zipimport.py", line 246, in load_module
submodname, is_package, fullpath, source = self._get_source(fullmodname)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/dist/py_zipimport.py", line 207, in _get_source
source = self.zipfile.read(relpath.replace(os.sep, '/'))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/zipfile.py", line 867, in read
return self.open(name, "r", pwd).read()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/zipfile.py", line 882, in open
zef_file = open(self.filename, 'rb')
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/dev_appserver_import_hook.py", line 578, in __init__
raise IOError(errno.EACCES, 'file not accessible', filename)
IOError: [Errno 13] file not accessible: '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg'
INFO 2012-01-21 20:50:44,222 dev_appserver.py:2832] "POST /manage HTTP/1.1" 500 -
一些说明:
- 在生产服务器上没有这个问题。
- 在开发服务器上,我的应用能正常运行几分钟,然后就会出现这个错误。
- 如果我在开发服务器上停止并重启我的应用,它又能正常工作几分钟。
- 我使用的是最新版本的 gae-pytz,你可以看到在导入时出现了错误。
- 我删除的[...]内容和你在最后看到的东西类似。
- 我不知道为什么在最后会调用setuptools。
- 我使用的是带有Lion系统的Mac。
我可以使用开发服务器,但每隔几分钟就得停下来重启一次,真的很烦人。有没有什么办法可以解决这个问题?
3 个回答
这个问题是出在使用Python 2.7的App Engine开发服务器上的一个错误。解决办法可以在这里找到:日志中的文件不可访问错误(setuptools)
我更喜欢的一个替代答案。
pytz的__init__.py
文件里有以下几行内容:
#try:
# from pkg_resources import resource_stream
#except ImportError:
resource_stream = None
我把前面三行注释掉了,这样问题就解决了。
从错误信息来看,问题出在你的代码试图从一个叫做 site-packages 的地方导入 setuptools,但开发服务器不支持这样做。
这个路径是:'/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg'
你需要把 setuptools 包含在你的应用代码中。偶尔能正常工作的原因可能是你的代码在不同模块之间的路径不同,或者(根据你在开发中测试的内容)不同的导入顺序导致 setuptools 在其他地方被导入,或者只在你代码的某些特定时刻需要。
看看错误信息的第四行,那里是导入 pytz 的,下一行是从 pkg_resources 导入 resource_stream,这就是引发后续导入问题的原因。我在我的项目根目录下使用了一个假的、简化版的 pkg_resources,这样就不会尝试从 setuptools 导入东西。你可以在调试导入模式下运行开发服务器,这样会告诉你更多信息。
这里有一个假的 pkg_resources。
"""Package resource API
--------------------
A resource is a logical file contained within a package, or a logical
subdirectory thereof. The package resource API expects resource names
to have their path parts separated with ``/``, *not* whatever the local
path separator is. Do not use os.path operations to manipulate resource
names being passed into the API.
The package resource API is designed to work with normal filesystem packages,
.egg files, and unpacked .egg files. It can also work in a limited way with
.zip files and with custom PEP 302 loaders that support the ``get_data()``
method.
"""
import sys, os, zipimport, time, re, imp, new
try:
frozenset
except NameError:
from sets import ImmutableSet as frozenset
from os import utime #, rename, unlink # capture these to bypass sandboxing
from os import open as os_open
可能还有其他更好的方法,但这个对我有效。
哦,我还建议你使用 http://code.google.com/p/gae-pytz/,而不是 pytz。
祝好