使py2exe与zope.interface兼容
我有一个基于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.interface
和zope
的各种组合添加到INCLUDES
和PACKAGES
中,但这样做只让我遇到了这个构建时错误:
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 个回答
我在Windows XP SP3上用py2exe创建一个包时遇到了问题。我发现py2exe没有正确识别依赖项。
为了解决这个问题,我卸载了我的第三方包,然后用下面这个easy_install命令重新安装它们。
easy_install -Z <your_package_name>
这里的-Z选项是用来解压包的内容,所以内容不会被压缩。现在你再运行py2exe,它就能正确识别依赖项了。
希望这对你有帮助!
我不知道你是否解决了这个问题,或者现在对你来说是否还有用,但为了将来搜索这个问题的人,我找到了一种简单的方法来修复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。
我遇到过和 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
友好的方式打包之前,这大概是最好的解决办法了。