diff --git a/shepherd/plugin.py b/shepherd/plugin.py index d02df0f..627bc90 100644 --- a/shepherd/plugin.py +++ b/shepherd/plugin.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 -from contextlib import suppress +import inspect from abc import ABC, abstractmethod import importlib +import logging from types import SimpleNamespace from collections import namedtuple @@ -10,6 +11,7 @@ import sys import os import shepherd.scheduler +log = logging.getLogger(__name__) class PluginLoadError(Exception): @@ -259,15 +261,22 @@ def find_plugins(plugin_names, plugin_dir=None): raise PluginLoadError("Could not find plugin "+plugin_name) # Scan imported module for Plugin subclass - attrs = [getattr(mod, name) for name in dir(mod)] - for attr in attrs: - with suppress(TypeError): - if issubclass(attr, Plugin): - plugin_classes[plugin_name] = attr - break + def is_module_plugin(member, module=mod): + return (inspect.isclass(member) and member.__module__ == + module.__name__ and issubclass(member, Plugin)) + + class_list = inspect.getmembers(mod, is_module_plugin) + + if class_list: + if len(class_list) > 1: + log.warning( + F"Plugin module {mod.__name__} has more than one shepherd.Plugin subclass.") + _, plugin_classes[plugin_name] = class_list[0] + log.info(F"Loading plugin {plugin_classes[plugin_name].__name__}" + " from module {mod.__name__}") else: - raise PluginLoadError("Imported shepherd plugin modules must contain a " - "subclass of shepherd.plugin.Plugin, such as" - "shepherd.plugin.SimplePlugin") + raise PluginLoadError("Imported shepherd plugin modules must contain a" + " subclass of shepherd.plugin.Plugin, such as" + " shepherd.plugin.SimplePlugin") return plugin_classes