首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pyinstaller打包twistd插件

使用pyinstaller打包twistd插件
EN

Stack Overflow用户
提问于 2012-04-17 05:18:24
回答 1查看 1.3K关注 0票数 5

我创建了一个很好的python Twisted应用程序,其中包含一个用于twistd运行器的插件,如Twisted文档中指定的:http://twistedmatrix.com/documents/current/core/howto/tap.html。我在使用PyInstaller打包时遇到了问题:在执行冻结的应用程序时,找不到我的twistd插件。

为了发布我的项目,我使用twistd runner模块创建了自己的顶级启动脚本,例如

代码语言:javascript
复制
#!/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插件(为了简洁而编辑):

代码语言:javascript
复制
~/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产生的可执行文件中是空的,例如

代码语言:javascript
复制
from twisted.plugin import IPlugin, getPlugins
plugins = list(getPlugins(IPlugin))
print "Twistd plugins=%s" % plugins

我使用了一个默认的PyInstaller规范文件,没有指定隐藏的导入或导入挂钩。

我喜欢twistd的日志记录,pid文件等功能,所以我想避免不得不完全放弃twistd runner来绕过插件问题。有没有办法确保我的twistd插件在冻结的可执行文件中被找到?

EN

回答 1

Stack Overflow用户

发布于 2012-04-17 23:59:59

通过对一些扭曲的代码进行逆向工程,我找到了一种解决方法。这里我对插件导入进行了硬编码。对我来说,这在PyInstaller上运行得很好。

代码语言:javascript
复制
#!/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()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10181868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档