summaryrefslogtreecommitdiff
path: root/poezio/plugin.py
diff options
context:
space:
mode:
Diffstat (limited to 'poezio/plugin.py')
-rw-r--r--poezio/plugin.py54
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):
"""