Application Plugin Framework

Ron ronpro at cox.net
Tue Nov 22 04:46:21 CET 2005


Hello,

I'm attempting to develop a  plugin framework for an application that I'm 
working on.  I wish to develop something in which all plugins exist in a 
directory tree.  The framework need only be given the root of the tree.  The 
framework then uses os.path.walk to search all for all files named 
'plugin.pyc'.  These are then loaded using imp.load_compiled().  They need 
contain only one variable called 'plugin' which is a reference to an 
instance of the plugin object.  This is extrated from the loaded module 
using getattr.  After that, the plugins are easy to work with since they 
implement a standard interface.  Or so the theory goes.  And this does work 
fine provided the plugin is implemented entirely within that one file.  If 
there are support modules that the main plugin module imports, which exist 
in the plugin's directory, then I get problems.  The imports fail.  I get 
"ImportError:  No module named <support module name>"

Here's PluginManager.py:
####################

import os


class PluginManager( object ):
   def __init__( self, pluginDir ):
      self._plugins = { }

      os.path.walk( pluginDir, self._addPlugin, None )

   def _addPlugin( self, arg, dirname, names ):
      import imp

      for filename in names:
         fullFilename = os.path.join( dirname, filename )
         if os.path.isfile( fullFilename ) and (filename == 'plugin.pyc'):
            module = imp.load_compiled( 'plugin', fullFilename )
            self._plugins[ plugin.name ] = getattr( module, 'plugin' )
            return

PM = PluginManager( r'C:\Personal\SWDev\ModuleTest' )     # Root of the 
plugin directory tree

print 'Plugin List: ', PM._plugins.keys()

for name,plugin in PM._plugins.iteritems():
   plugin.doSomething( )

print 'done!'

#######################
My plugin.py file is in C:\Personal\SWDev\ModuleTest\Plugins\MyPlugin.  It's 
called plugin.pyc (which I compiled from the following source by importing 
it into the interactive python shell.
#######################

import work


class MyPlugin( object ):
   def __init__( self ):
      self.name  = 'MyPlugin'

   def doSomething( self ):
      work.foo( )


plugin = MyPlugin( )

#######################
Finally, work.py is in the same directory as plugin.py
#######################

def foo( ):
   print 'foo called'

######################
Does anybody have any thoughts on how to get this, or something similar, to 
work?  I really just want to be able to load plugins into my app without 
having to modify my app's source code, or modify some list of plugins.  I 
also would like to allow each plugin to have its own subdirectory so they 
are easily installed or removed.

Thanks for your help.







More information about the Python-list mailing list