Source code for pluginmanager.plugin_manager

import inspect
from . import util
from .iplugin import IPlugin


[docs]class PluginManager(object): """ PluginManager manages the plugin state. It can automatically instantiate classes and enforce uniqueness, which it does by default. """
[docs] def __init__(self, unique_instances=True, instantiate_classes=True, plugins=None, blacklisted_plugins=None): """ `unique_instances` determines if all plugins have to be unique. This will also ensure that no two instances of the same class are tracked internally. `instantiate_classes` tracks to see if the class should automatically instantiate class objects that are passed in. `plugins` can be a single obj or iterable `blacklisted plugins` can be a single obj or iterable """ self.unique_instances = unique_instances self.instantiate_classes = instantiate_classes if plugins is None: plugins = [] if blacklisted_plugins is None: blacklisted_plugins = [] self.plugins = util.return_list(plugins) self.blacklisted_plugins = util.return_list(blacklisted_plugins)
[docs] def get_plugins(self, filter_function=None): """ Gets out the plugins from the internal state. Returns a list object. If the optional filter_function is supplied, applies the filter function to the arguments before returning them. Filters should be callable and take a list argument of plugins. """ plugins = self.plugins if filter_function is not None: plugins = filter_function(plugins) return plugins
[docs] def add_plugins(self, plugins): """ Adds plugins to the internal state. `plugins` may be a single object or an iterable. If `instantiate_classes` is True and the plugins have class instances in them, attempts to instatiate the classes. If `unique_instances` is True and duplicate instances are passed in, this method will not track the new instances internally. """ self._instance_parser(plugins)
[docs] def set_plugins(self, plugins): """ sets plugins to the internal state. `plugins` may be a single object or an iterable. If `instatntiate_classes` is True and the plugins have class instances in them, attempts to instatiate the classes. If `unique_instances` is True and duplicate instances are passed in, this method will not track the new instances internally. """ self.plugins = [] self._instance_parser(plugins)
[docs] def remove_plugins(self, plugins): """ removes `plugins` from the internal state `plugins` may be a single object or an iterable. """ util.remove_from_list(self.plugins, plugins)
[docs] def remove_instance(self, instances): """ removes `instances` from the internal state. Note that this method is syntatic sugar for the `remove_plugins` acts as a passthrough for that function. `instances` may be a single object or an iterable """ self.remove_plugins(instances)
def _get_instance(self, klasses): """ internal method that gets every instance of the klasses out of the internal plugin state. """ return [x for x in self.plugins if isinstance(x, klasses)]
[docs] def get_instances(self, filter_function=IPlugin): """ Gets instances out of the internal state using the default filter supplied in filter_function. By default, it is the class IPlugin. Can optionally pass in a list or tuple of classes in for `filter_function` which will accomplish the same goal. lastly, a callable can be passed in, however it is up to the user to determine if the objects are instances or not. """ if isinstance(filter_function, (list, tuple)): return self._get_instance(filter_function) elif inspect.isclass(filter_function): return self._get_instance(filter_function) elif filter_function is None: return self.plugins else: return filter_function(self.plugins)
[docs] def register_classes(self, classes): """ Register classes as plugins that are not subclassed from IPlugin. `classes` may be a single object or an iterable. """ classes = util.return_list(classes) for klass in classes: IPlugin.register(klass)
def _instance_parser(self, plugins): """ internal method to parse instances of plugins. Determines if each class is a class instance or object instance and calls the appropiate handler method. """ plugins = util.return_list(plugins) for instance in plugins: if inspect.isclass(instance): self._handle_class_instance(instance) else: self._handle_object_instance(instance) def _handle_class_instance(self, klass): """ handles class instances. If a class is blacklisted, returns. If uniuqe_instances is True and the class is unique, instantiates the class and adds the new object to plugins. If not unique_instances, creates and adds new instance to plugin state """ if (klass in self.blacklisted_plugins or not self.instantiate_classes or klass == IPlugin): return elif self.unique_instances and self._unique_class(klass): self.plugins.append(klass()) elif not self.unique_instances: self.plugins.append(klass()) def _handle_object_instance(self, instance): klass = type(instance) if klass in self.blacklisted_plugins: return elif self.unique_instances: if self._unique_class(klass): self.plugins.append(instance) else: return else: self.plugins.append(instance)
[docs] def activate_plugins(self): """ helper method that attempts to activate plugins checks to see if plugin has method call before calling it. """ for instance in self.get_instances(): if hasattr(instance, 'activate'): instance.activate()
[docs] def deactivate_plugins(self): """ helper method that attempts to deactivate plugins. checks to see if plugin has method call before calling it. """ for instance in self.get_instances(): if hasattr(instance, 'deactivate'): instance.deactivate()
def _unique_class(self, cls): """ internal method to check if any of the plugins are instances of a given cls """ return not any(isinstance(obj, cls) for obj in self.plugins)
[docs] def add_blacklisted_plugins(self, plugins): """ add blacklisted plugins. `plugins` may be a single object or iterable. """ plugins = util.return_list(plugins) self.blacklisted_plugins.extend(plugins)
[docs] def set_blacklisted_plugins(self, plugins): """ sets blacklisted plugins. `plugins` may be a single object or iterable. """ plugins = util.return_list(plugins) self.blacklisted_plugins = plugins
[docs] def get_blacklisted_plugins(self): """ gets blacklisted plugins tracked in the internal state Returns a list object. """ return self.blacklisted_plugins
[docs] def remove_blacklisted_plugins(self, plugins): """ removes `plugins` from the blacklisted plugins. `plugins` may be a single object or iterable. """ util.remove_from_list(self.blacklisted_plugins, plugins)