Format: text/x-python
⬇ Download File (1.4 KB)
   1  from functools import wraps
   2  
   3  
   4  class _PluginManager:
   5      def __init__(self):
   6          self._registered_plugins = []
   7          self._cached_base_callbacks = {}
   8          self._built_functions = {}
   9  
  10      def register(self, *plugins):
  11          """
  12          Makes it possible to register your plugin.
  13          """
  14          self._registered_plugins.extend(plugins)
  15          self._build_functions()
  16  
  17      def decorate(self, name=None):
  18          def decorator(callback):
  19              @wraps(callback)
  20              def wrapper(*args, **kwargs):
  21                  return built_functions[public_name](*args, **kwargs)
  22  
  23              public_name = name or callback.__name__
  24  
  25              assert public_name not in self._built_functions
  26              built_functions = self._built_functions
  27              built_functions[public_name] = callback
  28              self._cached_base_callbacks[public_name] = callback
  29  
  30              return wrapper
  31  
  32          return decorator
  33  
  34      def _build_functions(self):
  35          for name, callback in self._cached_base_callbacks.items():
  36              for plugin in reversed(self._registered_plugins):
  37                  # Need to reverse so the first plugin is run first.
  38                  try:
  39                      func = getattr(plugin, name)
  40                  except AttributeError:
  41                      pass
  42                  else:
  43                      callback = func(callback)
  44              self._built_functions[name] = callback
  45  
  46  
  47  plugin_manager = _PluginManager()
  48