Refactor plugin implementation

Also, LookupError gets raised on some methods if the hook doesn't exist.
Reason is, that not raising would be silently passing off a potential error.
1.4
IceArmy 2011-09-18 02:58:43 -07:00
parent f39c3d4be8
commit f9a281ef2a
1 changed files with 55 additions and 44 deletions

View File

@ -26,35 +26,45 @@ from glob import glob
hooks = defaultdict(dict) hooks = defaultdict(dict)
def _checkHookExists(create=False):
'''Decorator that will raise LookupError or create hook if hook doesn't exist'''
def outterWrap(func):
def innerWrap(*args, **kwargs):
if args[0] not in hooks:
if create:
hooks[args[0]]['count'] = 0
hooks[args[0]]['plugins'] = []
else:
raise LookupError("Hook '%s' was not found" % args[0])
return func(*args, **kwargs)
return innerWrap
return outterWrap
@_checkHookExists(True)
def add_action(hook, priority=10): def add_action(hook, priority=10):
'''Decorator to be used for registering a function to '''Decorator to be used for registering a function to
a specific hook. Functions with lower priority are a specific hook. Functions with lower priority are
executed first (priority of 1 for example). executed first (priority of 1 for example).
''' '''
def register(func): def register(func):
if hooks[hook].get('plugins') is not None:
hooks[hook]['plugins'].append((priority, func)) hooks[hook]['plugins'].append((priority, func))
else:
hooks[hook]['plugins'] = [(priority, func)]
return func return func
return register return register
@_checkHookExists()
def did_action(hook): def did_action(hook):
'''Find out how many times a hook was fired''' '''Find out how many times a hook was fired'''
if hooks[hook].get('count') is None:
hooks[hook]['count'] = 0
return hooks[hook]['count'] return hooks[hook]['count']
@_checkHookExists(True)
def do_action(hook, *args, **kwargs): def do_action(hook, *args, **kwargs):
'''Trigger a hook. It will run any functions that have registered '''Trigger a hook. It will run any functions that have registered
themselves to the hook. Any additional arguments or keyword themselves to the hook. Any additional arguments or keyword
arguments you pass in will be passed to the functions. arguments you pass in will be passed to the functions.
''' '''
if hooks[hook].get('count') is None:
hooks[hook]['count'] = 0
if hooks[hook].get('plugins') is not None:
# sort plugins by priority # sort plugins by priority
hooks[hook]['plugins'].sort() hooks[hook]['plugins'].sort()
for plugin in hooks[hook]['plugins']: for plugin in hooks[hook]['plugins']:
@ -62,7 +72,7 @@ def do_action(hook, *args, **kwargs):
plugin[1](*args, **kwargs) plugin[1](*args, **kwargs)
def get(name, depth=3, scope='local'): def get(name, depth=4, scope='local'):
'''Gets the value of a variable in the parents namespace '''Gets the value of a variable in the parents namespace
Args: Args:
@ -83,11 +93,13 @@ def has_action(hook, func=None):
'''Check if hook exists. If function is specified, '''Check if hook exists. If function is specified,
check if function has been registered for hook. check if function has been registered for hook.
''' '''
if hook in hooks:
if func is None: if func is None:
if hook in hooks:
return True return True
else: else:
if hooks[hook].get('plugins') is not None: if hook not in hooks:
raise LookupError("Hook '%s' was not found" % hook)
for plugin in hooks[hook]['plugins']: for plugin in hooks[hook]['plugins']:
if plugin[1] == func: if plugin[1] == func:
return True return True
@ -99,12 +111,14 @@ def remove_action(hook, func=None, priority=10):
remove function from hook. If priority is not same as remove function from hook. If priority is not same as
functions priority, it will not remove the function. functions priority, it will not remove the function.
''' '''
if hook in hooks:
if func is None: if func is None:
if hook in hooks:
del hooks[hook] del hooks[hook]
return True return True
else: else:
if hooks[hook].get('plugins') is not None: if hook not in hooks:
raise LookupError("Hook '%s' was not found" % hook)
for i, plugin in enumerate(hooks[hook]['plugins']): for i, plugin in enumerate(hooks[hook]['plugins']):
if plugin[1] == func and plugin[0] == priority: if plugin[1] == func and plugin[0] == priority:
del hooks[hook]['plugins'][i] del hooks[hook]['plugins'][i]
@ -112,27 +126,24 @@ def remove_action(hook, func=None, priority=10):
return False return False
@_checkHookExists()
def remove_all_actions(hook, priority=None): def remove_all_actions(hook, priority=None):
'''Remove all functions that have been registered to hook. '''Remove all functions that have been registered to hook.
If priority is used, remove all actions from that priority If priority is used, remove all actions from that priority
instead. instead.
''' '''
if hook in hooks:
if priority is None: if priority is None:
del hooks[hook][:] del hooks[hook][:]
else: else:
if hooks[hook].get('plugins') is not None:
indexes = [] indexes = []
for i, plugin in enumerate(hooks[hook]['plugins']): for i, plugin in enumerate(hooks[hook]['plugins']):
if plugin[0] == priority: if plugin[0] == priority:
indexes.append(i) indexes.append(i)
for index in indexes: for index in indexes:
del hooks[hook]['plugins'][index] del hooks[hook]['plugins'][index]
return True
return False
def set_(name, value, depth=3, scope='local'): def set_(name, value, depth=4, scope='local'):
'''Sets the value of a variable in the parents namespace '''Sets the value of a variable in the parents namespace
Args: Args: