stop (ab)using __subclasses__ isntead interrogating the imported plugin modules for a predefined list of the plugin classes they contain, and always instantiate them when they are imported. Add a test plugin only useful for doctest
This commit is contained in:
parent
9029e519f9
commit
01bb454d90
|
@ -4,11 +4,18 @@
|
||||||
"""plugin.py - Base plugin system
|
"""plugin.py - Base plugin system
|
||||||
|
|
||||||
>>> registry = PluginRegistry()
|
>>> registry = PluginRegistry()
|
||||||
|
>>> registry.instances
|
||||||
|
{}
|
||||||
>>> registry.load_plugins()
|
>>> registry.load_plugins()
|
||||||
>>> registry.get_plugins_by_capability('test')
|
>>> plugins = registry.get_plugins_by_capability('test')
|
||||||
[<testplugin.TestPlugin object at ...>]
|
>>> len(plugins)
|
||||||
|
1
|
||||||
|
>>> plugins[0] #doctest: +ELLIPSIS
|
||||||
|
<testplugin.TestPlugin object at 0x...>
|
||||||
>>> registry.get_plugins_by_capability('this_should_not_ever_exist')
|
>>> registry.get_plugins_by_capability('this_should_not_ever_exist')
|
||||||
[]
|
[]
|
||||||
|
>>> plugins[0].do_test()
|
||||||
|
'TestPluginWin'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -50,12 +57,16 @@ class PluginRegistry(borg.Borg):
|
||||||
sys.path.insert(0, self.path)
|
sys.path.insert(0, self.path)
|
||||||
files = os.listdir(self.path)
|
files = os.listdir(self.path)
|
||||||
for plugin in files:
|
for plugin in files:
|
||||||
if os.path.isfile(os.path.join(self.path, plugin)) and \
|
pluginpath = os.path.join(self.path, plugin)
|
||||||
plugin[-3:] == '.py':
|
if os.path.isfile(pluginpath) and plugin[-3:] == '.py':
|
||||||
dbg('PluginRegistry::load_plugins: Importing plugin %s' %
|
dbg('PluginRegistry::load_plugins: Importing plugin %s' %
|
||||||
plugin)
|
plugin)
|
||||||
try:
|
try:
|
||||||
__import__(plugin[:-3], None, None, [''])
|
module = __import__(plugin[:-3], None, None, [''])
|
||||||
|
for item in getattr(module, 'available'):
|
||||||
|
if item not in self.instances:
|
||||||
|
func = getattr(module, item)
|
||||||
|
self.instances[item] = func()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err('PluginRegistry::load_plugins: Importing plugin %s \
|
err('PluginRegistry::load_plugins: Importing plugin %s \
|
||||||
failed: %s' % (plugin, e))
|
failed: %s' % (plugin, e))
|
||||||
|
@ -64,17 +75,19 @@ failed: %s' % (plugin, e))
|
||||||
"""Return a list of plugins with a particular capability"""
|
"""Return a list of plugins with a particular capability"""
|
||||||
result = []
|
result = []
|
||||||
dbg('PluginRegistry::get_plugins_by_capability: searching %d plugins \
|
dbg('PluginRegistry::get_plugins_by_capability: searching %d plugins \
|
||||||
for %s' % (len(Plugin.__subclasses__()), capability))
|
for %s' % (len(self.instances), capability))
|
||||||
for plugin in Plugin.__subclasses__():
|
for plugin in self.instances:
|
||||||
if capability in plugin.capabilities:
|
if capability in self.instances[plugin].capabilities:
|
||||||
if not plugin in self.instances:
|
|
||||||
self.instances[plugin] = plugin()
|
|
||||||
result.append(self.instances[plugin])
|
result.append(self.instances[plugin])
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_all_plugins(self):
|
||||||
|
"""Return all plugins"""
|
||||||
|
return(self.instances)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import doctest
|
import doctest
|
||||||
sys.path.insert(0, 'plugins')
|
sys.path.insert(0, 'plugins')
|
||||||
import testplugin
|
|
||||||
(failed, attempted) = doctest.testmod()
|
(failed, attempted) = doctest.testmod()
|
||||||
print "%d/%d tests failed" % (failed, attempted)
|
print "%d/%d tests failed" % (failed, attempted)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import plugin
|
import plugin
|
||||||
|
|
||||||
|
# available must contain a list of all the classes that you want exposed
|
||||||
|
available = ['TestPlugin']
|
||||||
|
|
||||||
class TestPlugin(plugin.Plugin):
|
class TestPlugin(plugin.Plugin):
|
||||||
capabilities = ['test']
|
capabilities = ['test']
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import plugin
|
import plugin
|
||||||
|
|
||||||
|
available = ['LaunchpadURLHandler']
|
||||||
|
|
||||||
class LaunchpadURLHandler(plugin.Plugin):
|
class LaunchpadURLHandler(plugin.Plugin):
|
||||||
capabilities = ['url_handler']
|
capabilities = ['url_handler']
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue