diff options
Diffstat (limited to 'poezio/plugin.py')
-rw-r--r-- | poezio/plugin.py | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/poezio/plugin.py b/poezio/plugin.py index 7e67d09c..f38e47e2 100644 --- a/poezio/plugin.py +++ b/poezio/plugin.py @@ -3,6 +3,9 @@ Define the PluginConfig and Plugin classes, plus the SafetyMetaclass. These are used in the plugin system added in poezio 0.7.5 (see plugin_manager.py) """ + +from typing import Any, Dict, Set, Optional +from asyncio import iscoroutinefunction from functools import partial from configparser import RawConfigParser from poezio.timed_events import TimedEvent, DelayedEvent @@ -23,6 +26,7 @@ class PluginConfig(config.Config): def __init__(self, filename, module_name, default=None): config.Config.__init__(self, filename, default=default) self.module_name = module_name + self.default_section = module_name self.read() def get(self, option, default=None, section=None): @@ -42,7 +46,7 @@ class PluginConfig(config.Config): def read(self): """Read the config file""" - RawConfigParser.read(self, str(self.file_name)) + RawConfigParser.read(self.configparser, str(self.file_name)) if not self.has_section(self.module_name): self.add_section(self.module_name) @@ -61,7 +65,7 @@ class PluginConfig(config.Config): """Write the config to the disk""" try: with self.file_name.open('w') as fp: - RawConfigParser.write(self, fp) + RawConfigParser.write(self.configparser, fp) return True except IOError: return False @@ -74,9 +78,12 @@ class SafetyMetaclass(type): @staticmethod def safe_func(f): def helper(*args, **kwargs): + passthrough = kwargs.pop('passthrough', False) try: return f(*args, **kwargs) except: + if passthrough: + raise if inspect.stack()[1][1] == inspect.getfile(f): raise elif SafetyMetaclass.core: @@ -84,9 +91,25 @@ class SafetyMetaclass(type): SafetyMetaclass.core.information(traceback.format_exc(), 'Error') return None - + async def async_helper(*args, **kwargs): + passthrough = kwargs.pop('passthrough', False) + try: + return await f(*args, **kwargs) + except: + if passthrough: + raise + if inspect.stack()[1][1] == inspect.getfile(f): + raise + elif SafetyMetaclass.core: + log.error('Error in a plugin', exc_info=True) + SafetyMetaclass.core.information(traceback.format_exc(), + 'Error') + return None + if iscoroutinefunction(f): + return async_helper return helper + def __new__(meta, name, bases, class_dict): for k, v in class_dict.items(): if inspect.isfunction(v): @@ -379,28 +402,35 @@ class BasePlugin(object, metaclass=SafetyMetaclass): Class that all plugins derive from. """ - default_config = None + # Internal use only + _unloading = False + + default_config: Optional[Dict[Any, Any]] = None + dependencies: Set[str] = set() + # This dict will get populated when the plugin is initialized + refs: Dict[str, Any] = {} - def __init__(self, plugin_api, core, plugins_conf_dir): + def __init__(self, name, plugin_api, core, plugins_conf_dir): + self.__name = name self.core = core # More hack; luckily we'll never have more than one core object SafetyMetaclass.core = core - conf = plugins_conf_dir / (self.__module__ + '.cfg') + conf = plugins_conf_dir / (self.__name + '.cfg') try: self.config = PluginConfig( - conf, self.__module__, default=self.default_config) + conf, self.__name, default=self.default_config) except Exception: log.debug('Error while creating the plugin config', exc_info=True) - self.config = PluginConfig(conf, self.__module__) + self.config = PluginConfig(conf, self.__name) self._api = plugin_api[self.name] self.init() @property - def name(self): + def name(self) -> str: """ Get the name (module name) of the plugin. """ - return self.__module__ + return self.__name @property def api(self): @@ -501,12 +531,12 @@ class BasePlugin(object, metaclass=SafetyMetaclass): """ return self.api.del_tab_command(tab_type, name) - def add_event_handler(self, event_name, handler, position=0): + def add_event_handler(self, event_name, handler, *args, **kwargs): """ Add an event handler to the event event_name. An optional position in the event handler list can be provided. """ - return self.api.add_event_handler(event_name, handler, position) + return self.api.add_event_handler(event_name, handler, *args, **kwargs) def del_event_handler(self, event_name, handler): """ |