py2app打包的应用在别名模式下正常,但打包后不行

3 投票
1 回答
877 浏览
提问于 2025-04-17 05:45

我有一个使用pyobjc的应用程序,它只能在32位的Python环境下运行,并且使用了gevent库。在py2app的别名模式下,一切都运行得很好,但一旦我构建了一个应用程序包,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模块,但找不到它应该要修改的那个模块。这可能是猴子补丁功能的问题吗?

编辑:看起来find_module在我的py2app包中工作得不太好。有解决办法吗?我觉得这不是点状模块的问题,因为httplib并不是点状的(它是Python核心库的一部分)。

编辑2:所以问题确实出在imp.find_module上。使用import('httplib')而不是load_module可以解决这个问题,但我不得不删除sys.modules中对'httplib'的引用,因为如果它已经加载,就无法进行猴子补丁。我觉得这样做不太对,尽管构建的应用程序包运行正常(httplib现在被猴子补丁了,并且允许使用HTTPSConnection进行初始化)。有没有什么解决办法或修复这个py2app问题的方法?

1 个回答

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 要复杂一些,但至少可以在标准的 gevent 0.13 版本上运行。我还没有尝试过最近发布的 gevent 1.0 alpha 版本。

撰写回答