A plugin is a file that gets imported just like a regular Python module. Each plugin can be uniquely identified either by its absolute filename or its module name. The module name is only available once the plugin is loaded. Any objects (usually classes) that are specially marked will be made available by the plugin manager for later retrieval.
A class gets imported if it has an attribute _protocols which is a list of supported protocols (a protocol is identified by an arbitrary hashable object). Each class can be uniquely identified by its module name and class name.
Plugins are loaded by calling importPlugin() or importPlugins(). You can also register any class as plugin class any time by calling the register() function. When a plugin is loaded or an object is registered the plugin/object is represented by a descriptor class (PluginDescriptor resp. PluginObjectDescriptor). These descriptor objects contain information about the plugin/object. The object descriptor also holds a reference to the actual plugin object.
You can iterate over all currently available protocols via the iterProtocols() function. The iterProtoObjects() function can be used to iterate over all objects that support a particular protocol and iterObjects() can be used to iterate over all objects. The default iterator iterates over all plugin descriptors.
Example plugin class:
# file: plugin.py
class PluginClass:
_protocols = ["MyProtocol"]
def __init__(self):
...
...
And here’s how to use it:
# Load the plugin
pdesc = importPlugin("plugin.py")
if pdesc.status!=STATUS_OK:
# there was an error...
# Search a plugin class
objdesc = findObject("plugin.PluginClass")
# Create an instance of the plugin class...
PluginClass = objdesc.object
instance = PluginClass()
The actual functionality is implemented in the PluginManager class. However, the module creates a global instance of this class which can be accessed by the module functions. These functions just call the corresponding methods of the global plugin manager object. If you want to load plugins that should be stored separately from the plugins in your surrounding application then you can also create your own instance of the PluginManager class.
Loads a plugin file. The given file is executed, i.e. it is imported like a module. Any object (usually class or function) that has an attribute _protocols is stored in the plugin manager. This attribute is a list of protocol specifiers (which are just arbitrary hashable objects).
The file must have a suffix that is recognized as a module by the Python interpreter (one of the suffixes returned by imp.get_suffixes()), otherwise an UnknownFileType exception is thrown.
It is possible to load a plugin several times if overwrite is set to True. The new definitions override the previous ones. However, if references or instances to old objects are kept somewhere they still refer to the old definition. When writing a plugin you should always bear in mind that the file could be executed several times and write your initialization code accordingly.
The function returns a PluginDescriptor object which contains information about the imported plugin.
Import several plugins at once. plugins can be a single file/directory name or a sequence of file/directory names. Directories are recursively descended. out is a stream which is used to output status messages.
A PluginDescriptor object keeps the status information of a plugin file. It has the following attributes:
The absolute file name of the plugin.
A file descriptor tuple (suffix, mode, type) as returned by the get_suffixes() function in the imp module (type is one of imp.PY_SOURCE, imp.PY_COMPILED or imp.C_EXTENSION).
Number of imported objects (usually this should be number of classes + number of functions).
Number of imported classes.
Number of imported functions.
Status flags. If everything is ok the status is STATUS_OK, otherwise its a combination of STATUS_EXCEPTION and STATUS_DUPLICATE.
A string containing the traceback message (if the STATUS_EXCEPTION flag is set).
A list of object descriptors of all imported objects.
The module object of the imported plugin.
The name of the plugin module.
A PluginObjectDescriptor object keeps the status information of a plugin object. It has the following attributes and methods:
The actual plugin object.
The name of the object.
The PluginDescriptor of the associated plugin.
Status flags. If everything is ok the status is STATUS_OK, otherwise its STATUS_DUPLICATE.
Return the module name where the plugin object belongs to (or None).
Return the name under which the object is identified. This name is composed of the module name and the object name, separated by a dot.