py2app 编辑的应用程序在别名模式下正常运行,但在捆绑时无法正常运行

发布于 2024-12-14 08:38:02 字数 766 浏览 0 评论 0原文

我有一个 pyobjc 应用程序在仅 32 位的 python 版本中运行,它使用 gevent 库。在 py2app'ed 别名模式下一切都工作得很好,但是一旦我构建了应用程序包,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 问题有任何解决方法/修复吗?

I have a pyobjc app running in a 32-bit only python build that makes use of the gevent library. Everything works great in py2app'ed alias mode, but once I build an app bundle, the gevent module can't find the httplib library, even if it was bundled with the site-packages directory.

File "gevent/monkey.pyo", line 182, in patch_httplib
File "gevent/httplib.pyo", line 8, in <module>
ImportError: No module named httplib

I've tried false importing as suggested (even if the module seems to have been packaged), but to no avail. It can find the gevent.httplib module but not the module it's supposed to monkey patch. could this be a problem with the monkey patching feature?

EDIT: it looks like find_module isn't working properly with my py2app bundle. Is there a workaround to this? I don't think it's a problem with dotted modules as httplib isn't dotted (it's part of the core python libs)

EDIT 2: so it definitely is imp.find_module. Using import('httplib') instead of load_module fixes it, but I had to delete the reference to 'httplib' in sys.modules because it can't monkey patch if it's already loaded. I don't think this is the correct way to do it though, though the built app bundle works properly (httplib is now monkey patched and allows init with HTTPSConnection). Is there any workaround/fix to this py2app problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

丘比特射中我 2024-12-21 08:38:02

这有点棘手,涉及更多修补,但绝对可以解决:

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 版本。

It is a bit tricky and involves even more patching, but definitely solvable:

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()

This solution is more complex than simply modifying gevent.httplib, but at least works with the stock gevent 0.13 distribution. I haven't tried it with the recently released gevent 1.0 alpha versions yet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文