[PEAK] plugins, dynamic module loading

Phillip J. Eby pje at telecommunity.com
Mon Nov 24 12:04:27 EST 2003


At 11:52 AM 11/24/03 -0500, Bob Ippolito wrote:
>On Nov 24, 2003, at 11:17 AM, darryl wrote:
>
>>hey all,
>>
>>I'm writing a whole series of stupid jabber/irc bots. Right now i'm
>>working on dynamically loading modules/plugins. Here's what i'm doing
>>now:
>>
>>    def loadModules(self, path):
>>        for m in glob.glob("%s/*.py" % path):
>>            m = re.sub(path, "", m)
>>            m = re.sub(r'[/\\]', "", m)
>>            m = re.sub("\.py$", "", m)
>>            exec "import %s\nself.modules.append(%s.%s(self))\n" %(m,m,m)
>>            print "registered %s" %m
>>
>>It's very ugly :)
>
>Looks like Perl to me, what the heck are you thinking?  :)
>
>def loadModules(self, path):
>     self.modules.extend([
>         __import__(os.path.splitext(m)[0])
>         for m in os.path.listdir(path)
>         if os.path.splitext(m)[1] == '.py' or 
> os.path.exists(os.path.join(path, m, '__init__.py'))
>     ])
>
>This also has the advantage that it lets you use a package.  As with 
>yours, path must be in sys.path.


Heavens.  Y'all sure like to do things the hard way.  :)


Put this in the class:

     modules = binding.Obtain(PropertyName('bots.modules'))


And this in your .ini:

[bots]
modules = [
     importString('somepkg.mymodule1'),
     importString('somepkg.mymodule2'),
     ...
  ]


Or if you *must* be dynamic about it...

[bots]
modules = [
     importString('somepkg.'+x[:-3]) # strip the .py
     for x in 
importString('glob').glob(config.fileNearModule('somepkg','*.py'))
  ]


(By the way, 'importString' can be found in peak.util.imports, if you need 
to use it in Python code.  Expressions in '.ini' files get it in their 
default globals, since it's so often needed there.)




More information about the PEAK mailing list