11
\$\begingroup\$

Is there a better way to have a minimal Python plugin mechanism than the following?

(This was inspired from this post.)

import sys
import pkgutil
import os.path
import plugins
pluginsPath = os.path.dirname(plugins.__file__)
pluginModules = [name for _, name, _ in pkgutil.iter_modules([pluginsPath])]
dictOfPlugins = {}
for plugin in pluginModules:
    thePluginModuleName = "plugins."+plugin
    result = __import__(thePluginModuleName)
    dictOfPlugins[plugin] = sys.modules[thePluginModuleName]

(This does assume that all your plugins are in a directory called "plugins" and thus are modules in that package, and that that directory has a blank __init__.py file in it.)

If you wanted to look for a particular plugin, the name would be a key in the dictOfPlugins, and the module object itself would be the value. Assuming you knew what the interface to your Python plugin modules would be, this would seem to do the job. Is there a better way to do this?

\$\endgroup\$
  • \$\begingroup\$ I personally would go with the route of having the individual plugin hook themselves into the "plugins" module. Then you wouldn't have to assume they are anywhere. \$\endgroup\$ – James Khoury Jun 29 '11 at 7:12
  • \$\begingroup\$ @James How would you go about ensuring that the code within the plugin that would hook itself in got called? \$\endgroup\$ – Andrew Chen Jul 4 '11 at 23:48
  • 1
    \$\begingroup\$ something similar to the way you create template tags/filters in django? have a plugins.register() method and call that after the plugin declaration. (e.g. plugins.register('pluginModuleName') or plugins.register(pluginModule). Does that make sense? \$\endgroup\$ – James Khoury Jul 5 '11 at 1:18
  • \$\begingroup\$ @James that almost makes sense (and would reduce a few lines of this), but it seems to presuppose that all plugin code is in someplace where it is executed - which kind of means that we need to assume that they are somewhere, since we can't really execute everything everywhere - or am I not understanding you correctly? \$\endgroup\$ – Andrew Chen Jul 5 '11 at 11:36
  • \$\begingroup\$ You lost me somewhere. I mean that when you start up your project you would define which plugins you'd want to use. Then you'd access them via the plugins module? Thats where I get a bit vague. I'm not 100% sure how you'd do that. \$\endgroup\$ – James Khoury Jul 5 '11 at 23:12
6
\$\begingroup\$

Check out how Django apps work:

  • Plugins are genuine Python packages, so the standard tools can be used to install them
  • Plugins that are actually used must be in the PYTHONPATH and listed (only the package name) in the configuration.
  • There are scripts to help create, test, ... plugins
  • The plugin structure is extensible in all possible ways.
  • Plugins are reloaded when they change in development mode.

I'm not saying that you should use Django if you're not doing web development, but you can inspire your plugin system on it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.