使 py2exe 与 zope.interface 兼容

6

我有一个基于Twisted和PyGTK的Python应用程序。 Twisted本身依赖于zope.interface,但我不直接导入它。

不幸的是,当我尝试运行我的应用程序时,以下错误出现在错误日志中:

Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface
Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface
Traceback (most recent call last):
  File "tasks.py", line 4, in <module>
  File "ui\__init__.pyc", line 14, in <module>
  File "twisted\python\log.pyc", line 17, in <module>
ImportError: No module named zope.interface

我已尝试将zope.interfacezope的所有组合添加到INCLUDESPACKAGES中,但这样做只会给我带来这个构建时间错误:

running py2exe
*** searching for required modules ***
C:\Python26\lib\site-packages\py2exe\build_exe.py:16: DeprecationWarning: the sets module is deprecated
  import sets
Traceback (most recent call last):
  File "setup.py", line 75, in <module>
    'gtk/*.ui'
  File "C:\Python26\lib\distutils\core.py", line 152, in setup
    dist.run_commands()
  File "C:\Python26\lib\distutils\dist.py", line 975, in run_commands
    self.run_command(cmd)
  File "C:\Python26\lib\distutils\dist.py", line 995, in run_command
    cmd_obj.run()
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 243, in run
    self._run()
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 296, in _run
    self.find_needed_modules(mf, required_files, required_modules)
  File "C:\Python26\lib\site-packages\py2exe\build_exe.py", line 1306, in find_needed_modules
    mf.import_hook(f)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 719, in import_hook
    return Base.import_hook(self,name,caller,fromlist,level)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 136, in import_hook
    q, tail = self.find_head_package(parent, name)
  File "C:\Python26\lib\site-packages\py2exe\mf.py", line 204, in find_head_package
    raise ImportError, "No module named " + qname
ImportError: No module named zope

我的setup.py文件如下:

from distutils.core import setup
import py2exe

def find_data_files(source,target,patterns):
    # I've elided this, I doubt it's relevant to the problem
    # ...

INCLUDES = [
    'cairo',
    'pango',
    'pangocairo',
    'atk',
    'gobject',
    'gio',
]

PACKAGES = [
    'encodings',
]

setup(
    name = 'MyApp',
    description = 'My Application',
    version = '1.0',

    windows = [
                  {
                      'script': os.path.join('ui','tasks.py'),
                      'icon_resources': [
                            (1, os.path.join(
                                'ui','data','iconpack.ico'))
                        ],
                  }
              ],

    options = {
                  'py2exe': {
                      'packages': ','.join(PACKAGES),
                      'includes': ','.join(INCLUDES),
                  }
              },

    data_files = find_data_files(
                    'ui', 'ui', [
                        'data/*',
                        'gtk/*.ui'
                    ])

)

我该如何让py2exe构建这个项目?
3个回答

24

我不知道你是否已经解决了这个问题,或者它是否仍然与你有关,但是为了未来的搜索者,我在这里找到了解决zope导入问题的简单方法。

具体来说,请在PYTHONDIR/Lib/site-packages/zope目录下添加一个空的__init__.py文件。

我使用以下设置文件测试了这一点:twisted应用程序。

#!/usr/bin/env python
'''
File: setup.py
Author: Spencer Rathbun
Date: 07/24/2012
Description: Setup file for py2exe, converts client python script into executable.
'''
from distutils.core import setup
import py2exe

INCLUDES = [
    ''
]

PACKAGES = [
    'twisted'
]

setup(
        name = 'client',
        description = '',
        version = '1.0',

        console = [
            {"script":"client.py",
                "icon_resources":[
                    (1, "c:\python27\DLLs\py.ico")
                    ]
                }
            ],
        zipfile = None,

        options = {"py2exe":
            {"compressed": 1,
                "optimize": 1,
                "ascii": 0,
                "bundle_files": 1,

                "packages": ','.join(PACKAGES),
                "includes": ','.join(INCLUDES),
                }
            }
        )

现在Py2exe可以使用这个方法成功地为Twisted创建一个可执行文件,因为它依赖于zope。


这对我有用,我认为应该接受这个答案。 - Willem D'Haeseleer
是的,这绝对是最好的答案。谢谢。 - Bjoern Stiel
是的,对我来说起作用了,需要使用repoze(repoze.lru)模块,该模块由routes模块所需。 - digitalacorn

5
我曾遇到与zope.interface及其伙伴(如zope.component等)相同的问题,具体来说,这是py2exe搜索和发现包的方式以及zope包的安装方式存在问题所致。
zope是一个命名空间包,因此在其.pth文件中依赖一些古怪的导入逻辑(请参阅zope.interface-3.*.*-py2.*-nspkg.pth),以将其子包添加到python路径中。查看它在site-packages中的情况,你就会明白我的意思。 py2exe在“发现”这种类型的包时存在问题。 最终,我手动重打包了我使用的各种zope包并将其重新设置为标准模块工具在site-packages中,并重新运行py2exe,然后一切都很顺利。这是一个麻烦事,但在py2exe能够处理包装边缘情况或者zope包以py2exe友好的方式打包之前,这大概是你所能做的最好的办法。

我去检查了一下,以确保我在不违反他们的许可证的情况下可以这样做。是只有我吗,还是Zope公共许可证实际上没有包含在他们的任何发行版中? - detly
在实际的代码文件顶部有一个包含许可证的引用 - 这就是他们所需要的。你并没有违反许可证(即你实际上没有改变代码),只是修改了软件包在你的系统上的安装方式。这与py2exe将所有Python库打包到exe文件中所做的操作没有任何区别。 - Mark Gemmill
呃,在这里 - detly
啊,是的,有时候使用py2exe打包各种包需要些功夫。通常情况下,py2exe会很好地告诉您它遇到了哪些库的问题,但是有些(例如zope)需要一些调查。 py2exe网站上有许多提示等内容,但它有点杂乱无章,需要花费一些时间挖掘。我曾经使用wxPython、zope和其他几个库打包应用程序,这花费了我数日痛苦的时间来解决问题。一旦完成,一切就运行得很好。但要达成目标确实有点麻烦。 - Mark Gemmill
使用Spencer下面的非常简单的方法,可以避免需要重新打包。 - Adam Nemitoff
显示剩余3条评论

3
我在Windows XP SP3上使用py2exe创建包时遇到了问题。我发现py2exe无法正确地确定依赖关系。
为了解决这个问题,我卸载了第三方包并使用以下easy_install命令重新安装它们:
easy_install -Z -Z选项会解压缩包的详细信息,因此内容不会被压缩。现在运行py2exe,它将正确检测到依赖关系。
希望这可以帮助你!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接