Back to index

python-cliapp  1.20120630
hook.py
Go to the documentation of this file.
00001 # Copyright (C) 2009-2012  Lars Wirzenius
00002 # 
00003 # This program is free software; you can redistribute it and/or modify
00004 # it under the terms of the GNU General Public License as published by
00005 # the Free Software Foundation; either version 2 of the License, or
00006 # (at your option) any later version.
00007 # 
00008 # This program is distributed in the hope that it will be useful,
00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 # GNU General Public License for more details.
00012 # 
00013 # You should have received a copy of the GNU General Public License along
00014 # with this program; if not, write to the Free Software Foundation, Inc.,
00015 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016 
00017 
00018 '''Hooks with callbacks.
00019 
00020 In order to de-couple parts of the application, especially when plugins
00021 are used, hooks can be used. A hook is a location in the application
00022 code where plugins may want to do something. Each hook has a name and
00023 a list of callbacks. The application defines the name and the location
00024 where the hook will be invoked, and the plugins (or other parts of the
00025 application) will register callbacks.
00026 
00027 '''
00028 
00029 
00030 class Hook(object):
00031 
00032     '''A hook.'''
00033 
00034     def __init__(self):
00035         self.callbacks = []
00036         
00037     def add_callback(self, callback):
00038         '''Add a callback to this hook.
00039         
00040         Return an identifier that can be used to remove this callback.
00041 
00042         '''
00043 
00044         if callback not in self.callbacks:
00045             self.callbacks.append(callback)
00046         return callback
00047         
00048     def call_callbacks(self, *args, **kwargs):
00049         '''Call all callbacks with the given arguments.'''
00050         for callback in self.callbacks:
00051             callback(*args, **kwargs)
00052         
00053     def remove_callback(self, callback_id):
00054         '''Remove a specific callback.'''
00055         if callback_id in self.callbacks:
00056             self.callbacks.remove(callback_id)
00057 
00058 
00059 class FilterHook(Hook):
00060 
00061     '''A hook which filters data through callbacks.
00062     
00063     Every hook of this type accepts a piece of data as its first argument
00064     Each callback gets the return value of the previous one as its
00065     argument. The caller gets the value of the final callback.
00066     
00067     Other arguments (with or without keywords) are passed as-is to
00068     each callback.
00069     
00070     '''
00071     
00072     def call_callbacks(self, data, *args, **kwargs):
00073         for callback in self.callbacks:
00074             data = callback(data, *args, **kwargs)
00075         return data
00076