Find plugin interface and confspec

master
Tom Wilson 6 years ago
parent 74c8bbc5ab
commit ad200f4e3c

@ -5,8 +5,10 @@ import logging
import sys
import pkgutil
import pkg_resources
from configspec import ConfigSpecification
from .. import base_plugins
log = logging.getLogger(__name__)
@ -35,8 +37,66 @@ def plugin_attachment(hookname):
class PluginInterface():
@staticmethod
def _load_interface(module, plugin_name) -> "PluginInterface":
"""
Finds PluginInterface instance in a plugin and returns it.
"""
def is_plugininterface(member):
return isinstance(member, PluginInterface)
interface_list = inspect.getmembers(module, is_plugininterface)
if not interface_list:
raise PluginLoadError("Imported shepherd plugins must contain an instance"
" of PluginInterface")
if len(interface_list) > 1:
log.warning(F"Plugin module {module.__name__} has more"
F" than one PluginInterface instance.")
_, interface = interface_list[0]
interface._plugin_name = plugin_name
return interface
def _load_confspec(self, module):
"""
If not already registered, looks for a ConfigSpecification instance in a plugin,
using a blank one by default.
"""
if self._confspec is not None:
return
def is_confspec(member):
return isinstance(member, ConfigSpecification)
confspec_list = inspect.getmembers(module, is_confspec)
if not confspec_list:
self._confspec = ConfigSpecification()
if len(confspec_list) > 1:
log.warning(F"Plugin {self._plugin_name} has more"
F" than one root ConfigSpecification instance.")
self.register_confspec(confspec_list[0][1])
def _load_pluginclass(self, module):
pass
def __init__(self):
self._confspec = None
self._loaded = False
self._plugin_name = "<not yet loaded>"
def _load_guard(self):
if self._loaded:
raise PluginLoadError("Cannot call interface register functions once"
" plugin is loaded")
def register_confspec(self, confspec):
self._load_guard()
if not isinstance(confspec, ConfigSpecification):
raise PluginLoadError("confspec must be an instance of ConfigSpecification")
self._confspec = confspec
@property
def confspec(self):
@ -121,20 +181,8 @@ def load_plugin(plugin_name, plugin_dir=None):
if not mod:
raise PluginLoadError("Could not find plugin "+plugin_name)
# Scan imported module for PluginInterface instance
def is_plugininterface(member):
return isinstance(member, PluginInterface)
interface_list = inspect.getmembers(mod, is_plugininterface)
if not interface_list:
raise PluginLoadError("Imported shepherd plugins must contain an instance"
" of PluginInterface")
if len(interface_list) > 1:
log.warning(F"Plugin module {mod.__name__} has more"
F" than one PluginInterface instance.")
_, interface = interface_list[0]
interface = PluginInterface._load_interface(mod, plugin_name)
interface._load_confspec(mod)
# TODO Populate plugin interface

Loading…
Cancel
Save