<commit_before>import os

from pluginbase import PluginBase

from . import plugins
from .depgraph import DependencyGraph

plugin_base = PluginBase(package='unleash.plugins')


class PluginGraph(DependencyGraph):
    NAME_ATTR = 'PLUGIN_NAME'
    DEP_ATTR = 'PLUGIN_DEPENDS'

    def __init__(self, *args, **kwargs):
        super(PluginGraph, self).__init__(*args, **kwargs)
        self.plugin_mods = {}

    def add_plugin(self, plugin):
        name = getattr(plugin, self.NAME_ATTR)
        self.plugin_mods[name] = plugin

        self.add_obj(name, depends_on=getattr(plugin, self.DEP_ATTR, []))

    def collect_plugins(self):
        # discover and load plugins
        plugin_source = plugin_base.make_plugin_source(
            persist=True,
            searchpath=[os.path.dirname(plugins.__file__)]
        )

        with plugin_source:
            for plugin_name in plugin_source.list_plugins():
                pl = plugin_source.load_plugin(plugin_name)

                # skip modules without ``PLUGIN_NAME`` attribute
                if not hasattr(pl, self.NAME_ATTR):
                    continue

                self.add_plugin(pl)

    def notify(self, funcname, *args, **kwargs):
        rvs = []

        for plugin_name in self.resolve_order():<commit_msg>If a plugin dependency is missing, raise an InvocationError.<commit_after>import os

from pluginbase import PluginBase

from . import plugins
from .depgraph import DependencyGraph
from .exc import InvocationError

plugin_base = PluginBase(package='unleash.plugins')


class PluginGraph(DependencyGraph):
    NAME_ATTR = 'PLUGIN_NAME'
    DEP_ATTR = 'PLUGIN_DEPENDS'

    def __init__(self, *args, **kwargs):
        super(PluginGraph, self).__init__(*args, **kwargs)
        self.plugin_mods = {}

    def add_plugin(self, plugin):
        name = getattr(plugin, self.NAME_ATTR)
        self.plugin_mods[name] = plugin

        self.add_obj(name, depends_on=getattr(plugin, self.DEP_ATTR, []))

    def collect_plugins(self):
        # discover and load plugins
        plugin_source = plugin_base.make_plugin_source(
            persist=True,
            searchpath=[os.path.dirname(plugins.__file__)]
        )

        with plugin_source:
            for plugin_name in plugin_source.list_plugins():
                pl = plugin_source.load_plugin(plugin_name)

                # skip modules without ``PLUGIN_NAME`` attribute
                if not hasattr(pl, self.NAME_ATTR):
                    continue

                self.add_plugin(pl)

    def notify(self, funcname, *args, **kwargs):
        rvs = []

        for plugin_name in self.resolve_order():
            if not plugin_name in self.plugin_mods:
                raise InvocationError(
                    'Could not find plugin {}, which is required by {}'
                    .format(plugin_name, self.get_dependants(plugin_name)))

{'fraction_non_alphanumeric': 0.0932085932085932, 'fraction_numerical': 0.0, 'mean_word_length': 2.5121654501216546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3780832', 'n_tokens_mistral': 860, 'n_tokens_neox': 812, 'n_words': 186}