Imported Upstream version 1.2.1
[platform/upstream/python-nose.git] / nose / plugins / manager.py
index ce3e48a..4d2ed22 100644 (file)
@@ -17,6 +17,10 @@ The plugin managers provided with nose are:
 :class:`EntryPointPluginManager`
     This manager uses setuptools entrypoints to load plugins.
 
+:class:`ExtraPluginsPluginManager`
+    This manager loads extra plugins specified with the keyword
+    `addplugins`.
+
 :class:`DefaultPluginMananger`
     This is the manager class that will be used by default. If
     setuptools is installed, it is a subclass of
@@ -48,6 +52,7 @@ import inspect
 import logging
 import os
 import sys
+from itertools import chain as iterchain
 from warnings import warn
 import nose.config
 from nose.failure import Failure
@@ -218,8 +223,10 @@ class NoPlugins(object):
 
 
 class PluginManager(object):
-    """Base class for plugin managers. Does not implement loadPlugins, so it
-    may only be used with a static list of plugins.
+    """Base class for plugin managers. PluginManager is intended to be
+    used only with a static list of plugins. The loadPlugins() implementation
+    only reloads plugins from _extraplugins to prevent those from being
+    overridden by a subclass.
 
     The basic functionality of a plugin manager is to proxy all unknown
     attributes through a ``PluginProxy`` to a list of plugins.
@@ -231,6 +238,7 @@ class PluginManager(object):
 
     def __init__(self, plugins=(), proxyClass=None):
         self._plugins = []
+        self._extraplugins = ()
         self._proxies = {}
         if plugins:
             self.addPlugins(plugins)
@@ -256,8 +264,13 @@ class PluginManager(object):
                             if getattr(p, 'name', None) != new_name]
         self._plugins.append(plug)
 
-    def addPlugins(self, plugins):
-        for plug in plugins:
+    def addPlugins(self, plugins=(), extraplugins=()):
+        """extraplugins are maintained in a separate list and
+        re-added by loadPlugins() to prevent their being overwritten
+        by plugins added by a subclass of PluginManager
+        """
+        self._extraplugins = extraplugins
+        for plug in iterchain(plugins, extraplugins):
             self.addPlugin(plug)
 
     def configure(self, options, config):
@@ -275,7 +288,8 @@ class PluginManager(object):
         log.debug("Plugins enabled: %s", enabled)
 
     def loadPlugins(self):
-        pass
+        for plug in self._extraplugins:
+            self.addPlugin(plug)
 
     def sort(self):
         return sort_list(self._plugins, lambda x: getattr(x, 'score', 1), reverse=True)
@@ -361,9 +375,7 @@ class EntryPointPluginManager(PluginManager):
     def loadPlugins(self):
         """Load plugins by iterating the `nose.plugins` entry point.
         """
-        super(EntryPointPluginManager, self).loadPlugins()
         from pkg_resources import iter_entry_points
-
         loaded = {}
         for entry_point, adapt in self.entry_points:
             for ep in iter_entry_points(entry_point):
@@ -387,6 +399,7 @@ class EntryPointPluginManager(PluginManager):
                 else:
                     plug = plugcls()
                 self.addPlugin(plug)
+        super(EntryPointPluginManager, self).loadPlugins()
 
 
 class BuiltinPluginManager(PluginManager):
@@ -403,11 +416,12 @@ class BuiltinPluginManager(PluginManager):
 
 try:
     import pkg_resources
-    class DefaultPluginManager(BuiltinPluginManager, EntryPointPluginManager):
+    class DefaultPluginManager(EntryPointPluginManager, BuiltinPluginManager):
         pass
-except ImportError:
-    DefaultPluginManager = BuiltinPluginManager
 
+except ImportError:
+    class DefaultPluginManager(BuiltinPluginManager):
+        pass
 
 class RestrictedPluginManager(DefaultPluginManager):
     """Plugin manager that restricts the plugin list to those not