Implementing a plug-in mechanism
Weatherby,Gerard
gweatherby at uchc.edu
Wed Mar 15 18:06:18 EDT 2023
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
More information about the Python-list
mailing list