A simple hook system

"""A simple hook system, e.g. for use in Web applications.

:Copyright: 2009 `Jochen Kupperschmidt <http://homework.nwsnet.de/>`_
:Date: 14-Aug-2009
:License: MIT
"""

from collections import defaultdict
import warnings


class UnknownHookWarning(Warning):
    """Indicate an unknown hook."""


class HookRegistry(object):
    """A hook registry."""

    def __init__(self):
        self._hooks = defaultdict(list)

    def register(self, name, *funcs):
        """Register callables for a hook name."""
        self._hooks[name].extend(funcs)

    def call(self, name, *args, **kwargs):
        """Call callables registered for this hook."""
        funcs = self._hooks.get(name)
        if funcs is None:
            warnings.warn(name, UnknownHookWarning)
            return
        for func in funcs:
            func(name, *args, **kwargs)


# example usage

hook_registry = HookRegistry()

# Register some hypothetical functions for a hook name.
hook_registry.register('item_changed', update_item_cache, regenerate_subitems)

# Call the hook created above, so the registered callables are executed.
hook_registry.call('item_changed')