3879: Allow multiple versions of a plugin

svn: r15299
This commit is contained in:
Doug Blank 2010-05-01 21:30:15 +00:00
parent 39f4ac256f
commit 12918718f9
3 changed files with 57 additions and 12 deletions

View File

@ -287,7 +287,7 @@ class CLIManager(object):
Register the plugins at initialization time. Register the plugins at initialization time.
""" """
self._pmgr.reg_plugins(const.PLUGINS_DIR) self._pmgr.reg_plugins(const.PLUGINS_DIR)
self._pmgr.reg_plugins(const.USER_PLUGINS) self._pmgr.reg_plugins(const.USER_PLUGINS, append=False)
def startcli(errors, argparser): def startcli(errors, argparser):
""" """

View File

@ -96,7 +96,7 @@ class BasePluginManager(object):
self.__registereddir_set = set() self.__registereddir_set = set()
self.__loaded_plugins = {} self.__loaded_plugins = {}
def reg_plugins(self, direct): def reg_plugins(self, direct, append=True):
""" """
Searches the specified directory, and registers python plugin that Searches the specified directory, and registers python plugin that
are being defined in gpr.py files. are being defined in gpr.py files.
@ -118,6 +118,7 @@ class BasePluginManager(object):
if dirname.startswith(".") or dirname in ["po", "locale"]: if dirname.startswith(".") or dirname in ["po", "locale"]:
dirnames.remove(dirname) dirnames.remove(dirname)
# add the directory to the python search path # add the directory to the python search path
if append:
sys.path.append(dirpath) sys.path.append(dirpath)
# if the path has not already been loaded, save it in the # if the path has not already been loaded, save it in the
# registereddir_list list for use on reloading. # registereddir_list list for use on reloading.
@ -165,14 +166,13 @@ class BasePluginManager(object):
del self.__failmsg_list[index] del self.__failmsg_list[index]
else: else:
self.__attempt_list.append(filename) self.__attempt_list.append(filename)
plugin = pdata.mod_name
try: try:
_module = __import__(plugin) _module = self.import_plugin(pdata)
if need_reload: if need_reload:
# For some strange reason second importing of a failed plugin # For some strange reason second importing of a failed plugin
# results in success. Then reload reveals the actual error. # results in success. Then reload reveals the actual error.
# Looks like a bug in Python. # Looks like a bug in Python.
reload(_module) _module = self.reload(_module, pdata)
self.__success_list.append((filename, _module, pdata)) self.__success_list.append((filename, _module, pdata))
self.__modules[filename] = _module self.__modules[filename] = _module
self.__loaded_plugins[pdata.id] = _module self.__loaded_plugins[pdata.id] = _module
@ -183,6 +183,23 @@ class BasePluginManager(object):
return None return None
def import_plugin(self, pdata):
"""
Rather than just __import__(id), this will add the pdata.fpath
to sys.path first (if needed), import, and then reset path.
"""
if isinstance(pdata, basestring):
pdata = self.get_plugin(pdata)
if not pdata:
return None
if pdata.fpath not in sys.path:
sys.path.insert(0, pdata.fpath)
module = __import__(pdata.mod_name)
sys.path.pop(0)
else:
module = __import__(pdata.mod_name)
return module
def empty_managed_plugins(self): def empty_managed_plugins(self):
""" For some plugins, managed Plugin are used. These are only """ For some plugins, managed Plugin are used. These are only
reobtained from the registry if this method is called reobtained from the registry if this method is called
@ -216,7 +233,7 @@ class BasePluginManager(object):
#module already reloaded, a second plugin in same module #module already reloaded, a second plugin in same module
continue continue
try: try:
reload(plugin[1]) self.reload(plugin[1], pdata)
self.__modules[filename] = plugin[1] self.__modules[filename] = plugin[1]
self.__loaded_plugins[pdata.id] = plugin[1] self.__loaded_plugins[pdata.id] = plugin[1]
except: except:
@ -235,6 +252,15 @@ class BasePluginManager(object):
for (filename, message, pdata) in oldfailmsg: for (filename, message, pdata) in oldfailmsg:
self.load_plugin(pdata) self.load_plugin(pdata)
def reload(self, module, pdata):
"""
"""
try:
reload(module)
except:
module = self.import_plugin(pdata)
return module
def get_fail_list(self): def get_fail_list(self):
""" Return the list of failed plugins. """ """ Return the list of failed plugins. """
return self.__failmsg_list return self.__failmsg_list

View File

@ -137,6 +137,22 @@ END = 2
# Functions and classes # Functions and classes
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def myint(s):
"""
Protected version of int()
"""
try:
v = int(s)
except:
v = s
return v
def version(sversion):
"""
Return the tuple version of a string version.
"""
return tuple([myint(x or "0") for x in (sversion + "..").split(".")])
def valid_plugin_version(plugin_version_string): def valid_plugin_version(plugin_version_string):
""" """
Checks to see if string is a valid version string for this version Checks to see if string is a valid version string for this version
@ -1067,15 +1083,17 @@ class PluginRegister(object):
def get_plugin(self, id): def get_plugin(self, id):
"""Return the PluginData for the plugin with id""" """Return the PluginData for the plugin with id"""
for x in self.__plugindata: matches = [x for x in self.__plugindata if x.id == id]
if x.id == id: matches.sort(key=lambda x: version(x.version))
return x if len(matches) > 0:
return matches[-1]
return None return None
def type_plugins(self, ptype): def type_plugins(self, ptype):
"""Return a list of PluginData that are of type ptype """Return a list of PluginData that are of type ptype
""" """
return [x for x in self.__plugindata if x.ptype == ptype] return [self.get_plugin(id) for id in
set([x.id for x in self.__plugindata if x.ptype == ptype])]
def report_plugins(self, gui=True): def report_plugins(self, gui=True):
"""Return a list of gui or cli PluginData that are of type REPORT """Return a list of gui or cli PluginData that are of type REPORT
@ -1158,4 +1176,5 @@ class PluginRegister(object):
def filter_load_on_reg(self): def filter_load_on_reg(self):
"""Return a list of PluginData that have load_on_reg == True """Return a list of PluginData that have load_on_reg == True
""" """
return [x for x in self.__plugindata if x.load_on_reg == True] return [self.get_plugin(id) for id in
set([x.id for x in self.__plugindata if x.load_on_reg == True])]