当IPlugin扩展时,Yapsy实例化了错误的类

时间:2014-07-04 22:09:29

标签: python plugins

我有以下文件结构,它使用Yapsy实现了一个非常简单的插件架构。

插件/ BasePlugin.py

from yapsy.IPlugin import IPlugin

class BasePlugin(IPlugin):
    def process(self):
        # Do some stuff common to all plugins
        pass

插件/ TestPlugin.py

from Plugins.BasePlugin import BasePlugin

class TestPlugin(BasePlugin):
    def process(self, info):
        super(TestPlugin, self).process()
        # Do stuff
        return "done"

test.py

from yapsy.PluginManager import PluginManager
from Plugins.BasePlugin import BasePlugin
import logging

logging.basicConfig(level=logging.DEBUG)
# See note 1
manager = PluginManager()   # Does not work
manager = PluginManager(categories_filter={'BasePlugin': BasePlugin}) # Works

def init_plugins():
    # Load the plugins from the plugin directory.
    manager.setPluginPlaces(["Plugins"])
    manager.collectPlugins()

    # Loop round the plugins and print their names.
    for plugin in manager.getAllPlugins():
        manager.activatePluginByName(plugin.name, "BasePlugin")
        print "Plugin path: {}".format(plugin.path)
        print "Plugin obj:  {}".format(plugin.plugin_object)

        result = plugin.plugin_object.process(info)

TestPlugin还有正确的.yapsy-plugin信息文件。

没有过滤器(注1)Yapsy尝试实例化BasePlugin而不是我的TestPlugin,尽管插件的名称是“TestPlugin”。例如:

Plugin path: /home/user/python/Plugins/TestPlugin
Plugin obj:  <Plugins.BasePlugin.BasePlugin object at 0x7f159af22050>

如果我包含过滤器,那么插件会正确加载,我的TestPlugin类会被实例化并改为使用。

DEBUG:yapsy:Activating plugin: BasePlugin.test
Plugin path: /home/david/python/Plugins/TestPlugin
Plugin obj:  <yapsy_loaded_plugin_test_0.TestPlugin object at 0x7f4dad7d4050>

我是否在继承上做错了,或者这就是Yapsy的工作方式?我不明白为什么它会尝试使用BasePlugin而不是TestPlugin,尽管找到了正确的文件。

我是否需要实现类别以扩展IPlugin并提供我自己的基类?

1 个答案:

答案 0 :(得分:3)

您遇到了一个已知的yapsy问题,该问题与检测文件中的插件并对其进行分类的方式有关。

https://yapsy.readthedocs.org/en/latest/Advices.html#plugin-class-detection-caveat的yapsy的文档的问题排查部分对此进行了解释。

由于这些已经是我自己的话,我只是将它们复制粘贴在这里,但如果有些事情不清楚,请随意询问精确度。


每个模块必须只定义一个插件。这意味着您不能拥有两个指向同一模块的插件描述文件。

由于“继承分类”系统,您不能直接在主插件文件中导入IPlugin的子类,而是导入其包含模块并使您的插件类继承自ContainingModule.SpecificPluginClass如下例所示。

以下代码不起作用(类MyBasePluginClass将被检测为插件的实现,而不是MyPlugin):

from myapp.plugintypes import MyBasePluginClass

class MyPlugin(MyBasePluginClass):
    pass

相反,您应该执行以下操作:

import myapp.plugintypes as plugintypes

class MyPlugin(plugintypes.MyBasePluginClass):
    pass