Browse Source

Make internal marked plugins accessible via pluggy's default methods

Peter Justin 7 years ago
parent
commit
6cc58c24aa
2 changed files with 57 additions and 18 deletions
  1. 3 4
      flaskbb/app.py
  2. 54 14
      flaskbb/plugins/manager.py

+ 3 - 4
flaskbb/app.py

@@ -413,15 +413,14 @@ def load_plugins(app):
     # have to find all the flaskbb modules that are loaded this way
     # have to find all the flaskbb modules that are loaded this way
     # otherwise sys.modules might change while we're iterating it
     # otherwise sys.modules might change while we're iterating it
     # because of imports and that makes Python very unhappy
     # because of imports and that makes Python very unhappy
-    # Converting it to a set is neccessary because we are not interested
-    # in duplicated plugins or invalid ones ('None' - appears on py2)
+    # we are not interested in duplicated plugins or invalid ones
+    # ('None' - appears on py2) and thus using a set
     flaskbb_modules = set(
     flaskbb_modules = set(
         module for name, module in iteritems(sys.modules)
         module for name, module in iteritems(sys.modules)
         if name.startswith('flaskbb')
         if name.startswith('flaskbb')
     )
     )
     for module in flaskbb_modules:
     for module in flaskbb_modules:
-        app.pluggy.register(module)
-        app.pluggy.mark_as_internal_plugin(module)
+        app.pluggy.register(module, internal=True)
 
 
     try:
     try:
         with app.app_context():
         with app.app_context():

+ 54 - 14
flaskbb/plugins/manager.py

@@ -31,28 +31,64 @@ class FlaskBBPluginManager(pluggy.PluginManager):
         self._plugin_metadata = {}
         self._plugin_metadata = {}
         self._disabled_plugins = []
         self._disabled_plugins = []
 
 
+        # we maintain a seperate dict for flaskbb.* internal plugins
         self._internal_name2plugin = {}
         self._internal_name2plugin = {}
 
 
-    def mark_as_internal_plugin(self, plugin):
-        """Marks a plugin as an internal FlaskBB plugin.
-        Returns the name of the plugin or None.
+    def register(self, plugin, name=None, internal=False):
+        """Register a plugin and return its canonical name or None
+        if the name is blocked from registering.
+        Raise a ValueError if the plugin is already registered.
+        """
+        # internal plugins are stored in self._plugin2hookcallers
+        name = super(FlaskBBPluginManager, self).register(plugin, name)
+        if not internal:
+            return name
+
+        self._internal_name2plugin[name] = self._name2plugin.pop(name)
+        return name
 
 
-        :param plugin: The plugin object to mark as internal
-                       FlaskBB plugin.
-        :param force: If set to ``True`` it will overwrite plugins which
-                      are already marked as internal.
+    def unregister(self, plugin=None, name=None):
+        """Unregister a plugin object and all its contained hook implementations
+        from internal data structures.
         """
         """
+        plugin = super(FlaskBBPluginManager, self).unregister(
+            plugin=plugin, name=name
+        )
+
         name = self.get_name(plugin)
         name = self.get_name(plugin)
-        if name not in self._name2plugin:
-            return None
+        if self._internal_name2plugin.get(name):
+            del self._internal_name2plugin[name]
+
+        return plugin
 
 
-        # already marked as internal
-        if name in self._internal_name2plugin:
-            self._name2plugin.pop(name)
+    def set_blocked(self, name):
+        """Block registrations of the given name, unregister if already
+        registered.
+        """
+        super(FlaskBBPluginManager, self).set_blocked(name)
+        self._internal_name2plugin[name] = None
+
+    def is_blocked(self, name):
+        """Return True if the name blockss registering plugins of that name."""
+        blocked = super(FlaskBBPluginManager, self).is_blocked(name)
+
+        return blocked or name in self._internal_name2plugin and \
+            self._internal_name2plugin[name] is None
+
+    def get_plugin(self, name):
+        """Return a plugin or None for the given name. """
+        plugin = super(FlaskBBPluginManager, self).get_plugin(name)
+        return self._internal_name2plugin.get(name, plugin)
+
+    def get_name(self, plugin):
+        """Return name for registered plugin or None if not registered."""
+        name = super(FlaskBBPluginManager, self).get_name(plugin)
+        if name:
             return name
             return name
 
 
-        self._internal_name2plugin[name] = self._name2plugin.pop(name)
-        return name
+        for name, val in self._internal_name2plugin.items():
+            if plugin == val:
+                return name
 
 
     def load_setuptools_entrypoints(self, entrypoint_name):
     def load_setuptools_entrypoints(self, entrypoint_name):
         """Load modules from querying the specified setuptools entrypoint name.
         """Load modules from querying the specified setuptools entrypoint name.
@@ -97,6 +133,10 @@ class FlaskBBPluginManager(pluggy.PluginManager):
         """Returns only the enabled plugin names."""
         """Returns only the enabled plugin names."""
         return list(self._name2plugin.keys())
         return list(self._name2plugin.keys())
 
 
+    def list_internal_name_plugin(self):
+        """Returns a list of internal name/plugin pairs."""
+        return self._internal_name2plugin.items()
+
     def list_plugin_metadata(self):
     def list_plugin_metadata(self):
         """Returns the metadata for all plugins"""
         """Returns the metadata for all plugins"""
         return self._plugin_metadata
         return self._plugin_metadata