Source code for maidenhair.utils.plugins

#!/usr/bin/env python
"""
A plugin registry module

"""
__author__  = 'Alisue (lambdalisue@hashnote.net)'
__all__ = (
    'Registry',
    'registry',
)
import os
import sys
from bunch import Bunch
from maidenhair.utils import environment


[docs]class Registry(object): """ A registry class which store plugin objects """ """entry_point for plugins""" ENTRY_POINT = 'maidenhair.plugins' def __init__(self): self.raw = Bunch()
[docs] def find(self, name, namespace=None): """ Find plugin object Parameters ---------- name : string A name of the object entry or full namespace namespace : string, optional A period separated namespace. E.g. `foo.bar.hogehoge` Returns ------- instance An instance found Raises ------ KeyError If the named instance have not registered Examples -------- >>> registry = Registry() >>> registry.register('hello', 'goodbye') >>> registry.register('foo', 'bar', 'hoge.hoge.hoge') >>> registry.register('foobar', 'foobar', 'hoge.hoge') >>> registry.find('hello') == 'goodbye' True >>> registry.find('foo', 'hoge.hoge.hoge') == 'bar' True >>> registry.find('hoge.hoge.foobar') == 'foobar' True """ if "." in name: namespace, name = name.rsplit(".", 1) caret = self.raw if namespace: for term in namespace.split('.'): if term not in caret: caret[term] = Bunch() caret = caret[term] return caret[name]
[docs] def register(self, name, obj, namespace=None): """ Register :attr:`obj` as :attr:`name` in :attr:`namespace` Parameters ---------- name : string A name of the object entry obj : instance A python object which will be registered namespace : string, optional A period separated namespace. E.g. `foo.bar.hogehoge` Examples -------- >>> registry = Registry() >>> registry.register('hello', 'goodbye') >>> registry.raw.hello == 'goodbye' True >>> registry.register('foo', 'bar', 'hoge.hoge.hoge') >>> isinstance(registry.raw.hoge, Bunch) True >>> isinstance(registry.raw.hoge.hoge, Bunch) True >>> isinstance(registry.raw.hoge.hoge.hoge, Bunch) True >>> registry.raw.hoge.hoge.hoge.foo == 'bar' True >>> registry.register('hoge.hoge.foobar', 'foobar') >>> registry.raw.hoge.hoge.hoge.foo == 'bar' True >>> registry.raw.hoge.hoge.foobar == 'foobar' True """ if "." in name: namespace, name = name.rsplit(".", 1) caret = self.raw if namespace: for term in namespace.split('.'): if term not in caret: caret[term] = Bunch() caret = caret[term] caret[name] = obj
[docs] def load_plugins(self, plugin_dirs=None, quiet=True): """ Load plugins in `sys.path` and :attr:`plugin_dirs` Parameters ---------- plugin_dirs : list or tuple of string, optional A list or tuple of plugin directory path quiet : bool, optional If True, print all error message """ from pkg_resources import working_set from pkg_resources import iter_entry_points from pkg_resources import Environment if plugin_dirs is None: plugin_dirs = [] plugin_dirs.append(environment.get_system_plugins_directory()) plugin_dirs.append(environment.get_user_plugins_directory()) distributions, errors = working_set.find_plugins( Environment(plugin_dirs) ) map(working_set.add, distributions) if not quiet: # display error info for distribution, error in errors: print distrubution, error for entry_point in iter_entry_points(self.ENTRY_POINT): # load entry point plugin = entry_point.load() # if plugin is callable and `manually` is True, initialize manually if callable(plugin) and getattr(plugin, 'manually', False): # manually initialize plugin plugin(self) else: # automatically initialize plugin self.register(entry_point.name, plugin)
"""A plugin registry""" registry = Registry() registry.load_plugins(quiet=False) if __name__ == '__main__': import doctest; doctest.testmod()