I do something similar to Thomas. (Also MIT licensed). I like objects. I like type hints.
Each plugin needs to have check and purpose functions and accepts either PluginSpec (by default) or AddonSpec if it defines addon = True This requires a single-level plugin directory with no extra files in it (unless they start with _, like __init__.py) And I should use os.path.splitext but I forget what’s it called and find it easier just to split. # noinspection PyUnresolvedReferences @dataclass class NamedModule: """Datacheck module and its name""" mod: object name: str def __post_init__(self): """Validate attributes""" assert hasattr(self.mod, 'check') assert hasattr(self.mod, 'purpose') def check(self, inspec: Union[PluginSpec, AddonSpec]) -> PluginResult: return self.mod.check(inspec) @property def purpose(self) -> str: return self.mod.purpose() @property def addon(self) -> bool: """Return true if this module uses AddonSpec""" return getattr(self.mod, 'addon', False) class Integrity: @property def plugins(self) -> List[NamedModule]: """Get list of plugins by scanning plugin directory""" modules = [] us = os.path.abspath(__file__) plugin_dir = os.path.join(os.path.dirname(us), 'plugins') de: os.DirEntry for de in os.scandir(plugin_dir): if not de.name.startswith('_'): n = de.name.split('.')[0] mod = importlib.import_module(f'.plugins.{n}', 'dataintegrity') modules.append(NamedModule(mod, n)) return modules -- https://mail.python.org/mailman/listinfo/python-list