我创建了一个很好的python Twisted应用程序,其中包含一个用于twistd运行器的插件,如Twisted文档中指定的:http://twistedmatrix.com/documents/current/core/howto/tap.html。我在使用PyInstaller打包时遇到了问题:在执行冻结的应用程序时,找不到我的twistd插件。
为了发布我的项目,我使用twistd runner模块创建了自己的顶级启动脚本,例如
#!/usr/bin/env python
from twisted.scripts.twistd import run
from sys import argv
argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
'myapp_plugin'
]
run()接下来,我使用PyInstaller将其冻结为单目录部署。执行上面冻结的脚本失败,因为它找不到我的twistd插件(为了简洁而编辑):
~/pyinstall/dist/bin/mystartup?16632/twisted/python/modules.py:758:
UserWarning: ~/pyinstall/dist/mystartup?16632 (for module twisted.plugins)
not in path importer cache (PEP 302 violation - check your local configuration).
~/pyinstall/dist/bin/mystartup: Unknown command: myapp_plugin通常,Twistd会检查Python系统路径,以发现我的插件位于twisted/plugins/myapp_plugin.py中。如果我在启动脚本中打印twistd插件的列表,那么这个列表在PyInstaller产生的可执行文件中是空的,例如
from twisted.plugin import IPlugin, getPlugins
plugins = list(getPlugins(IPlugin))
print "Twistd plugins=%s" % plugins我使用了一个默认的PyInstaller规范文件,没有指定隐藏的导入或导入挂钩。
我喜欢twistd的日志记录,pid文件等功能,所以我想避免不得不完全放弃twistd runner来绕过插件问题。有没有办法确保我的twistd插件在冻结的可执行文件中被找到?
发布于 2012-04-17 23:59:59
通过对一些扭曲的代码进行逆向工程,我找到了一种解决方法。这里我对插件导入进行了硬编码。对我来说,这在PyInstaller上运行得很好。
#!/usr/bin/env python
import sys
from twisted.application import app
from twisted.scripts.twistd import runApp, ServerOptions
import myapp_plugin as myplugin
plug = myplugin.serviceMaker
class MyServerOptions(ServerOptions):
"""
See twisted.application.app.ServerOptions.subCommands().
Override to specify a single plugin subcommand and load the plugin
explictly.
"""
def subCommands(self):
self.loadedPlugins = {plug.tapname:plug}
yield (plug.tapname,
None,
# Avoid resolving the options attribute right away, in case
# it's a property with a non-trivial getter (eg, one which
# imports modules).
lambda plug=plug: plug.options(),
plug.description)
subCommands = property(subCommands)
def run():
"""
Replace twisted.application.app.run()
To use our ServerOptions.
"""
app.run(runApp, MyServerOptions)
sys.argv[1:] = [
'--pidfile', '/var/run/myapp.pid',
'--logfile', '/var/run/myapp.log',
plug.tapname] + sys.argv[1:]
run()https://stackoverflow.com/questions/10181868
复制相似问题