我有一个pyobjc应用程序在一个32位的python构建中运行,它使用了gevent库。在py2app'ed别名模式下,一切都很好用,但是一旦我构建了一个app bundle,gevent模块就找不到httplib库,即使它与site-packages目录捆绑在一起。
File "gevent/monkey.pyo", line 182, in patch_httplib
File "gevent/httplib.pyo", line 8, in <module>
ImportError: No module named httplib
我按照建议尝试了虚假导入(即使模块似乎已打包),但无济于事。它可以找到gevent.httplib模块,但不能找到它应该修补的模块。这可能是猴子修补功能的问题吗?
编辑:看起来我的py2app包找不到find_module。这有解决方法吗?我不认为这是虚线模块的问题,因为httplib没有点缀(它是核心python库的一部分)
编辑2:所以肯定是imp.find_module。使用 import ('httplib')而不是load_module修复了它,但我不得不删除sys.modules中对'httplib'的引用,因为如果它已经加载,它就不能修补它。我不认为这是正确的方法,尽管构建的应用程序包正常工作(httplib现在是猴子修补,并允许使用HTTPSConnection初始化)。是否有任何解决方法/修复此py2app问题?
答案 0 :(得分:2)
这有点棘手,涉及更多补丁,但绝对可以解决:
def main():
# Patch the imp standard library module to fix an incompatibility between
# py2app and gevent.httplib while running a py2app build on Mac OS-X.
# This patch must be executed before applying gevent's monkey patching.
if getattr(sys, 'frozen', None) == 'macosx_app':
import imp, httplib
original_load_module = imp.load_module
original_find_module = imp.find_module
def custom_load_module(name, file, pathname, description):
if name == '__httplib__':
return httplib
return original_load_module(name, file, pathname, description)
def custom_find_module(name, path=None):
if name == 'httplib':
return (None, None, None)
return original_find_module(name, path)
imp.load_module = custom_load_module
imp.find_module = custom_find_module
# Verify that the patch is working properly (you can remove these lines safely)
__httplib__ = imp.load_module('__httplib__', *imp.find_module('httplib'))
assert __httplib__ is httplib
# Your application here
if __name__ == '__main__':
main()
这个解决方案比简单修改gevent.httplib
更复杂,但至少可以使用stock gevent 0.13发行版。我还没有尝试过最近发布的gevent 1.0 alpha版本。