plugin development best practices

Flavio fccoelho at gmail.com
Thu Feb 22 13:50:15 EST 2007


On Feb 22, 2:04 pm, "Paul Boddie" <p... at boddie.org.uk> wrote:
> On 22 Feb, 16:13, "Diez B. Roggisch" <d... at nospam.web.de> wrote:
>
>
>
> > Darn. You're right of course - I just got the basic idea, and formed in my
> > mind the "get the modules filename, thus the path, glob over it for *py,
> > and thus get the subsequent module names"-pattern. Which is trivial of
> > course, but not as trivial as just dir(module)
>
> The __init__.py file of a plugins package could contain something like
> this:
>
> # Start
> def init():
>     import os
>     global __all__
>     this_dir = os.path.split(__file__)[0]
>     py_suffix = os.path.extsep + "py"
>     __all__ = []
>     for filename in os.listdir(this_dir):
>         if os.path.isdir(os.path.join(this_dir, filename)) and \
>             os.path.exists(os.path.join(this_dir, filename, "__init__"
> + py_suffix)):
>             __all__.append(filename)
>         else:
>             module, suffix = os.path.splitext(filename)
>             if suffix == py_suffix and module != "__init__":
>                 __all__.append(module)
> init()
> del init
> # End
>
> This should populate the __all__ attribute of the package with then
> names of any submodules or subpackages. Although that in itself won't
> provide the names of the plugins via the dir function, the __all__
> attribute is some kind of standard, and things like "from plugins
> import *" will import all the known plugins. In fact, if you add such
> an import statement to the end of the above code, you'll get all the
> names of the plugins stored within the package (and thus returned by
> the dir function) because the submodules and subpackages will actually
> have been imported. Even reloading the plugins package will update the
> __all__ attribute, although things like the unloading or removal of
> plugins might be challenging in a solution where such things are
> automatically imported.
>
> Having a variation of the above function in the standard library could
> be fairly useful, I suppose.
>
> Paul

Hi Paul,

Thanks for the fix. I had not tested my idea.

anyway here goes another solution:

I create a plugins package containing a single plugin named a.py, with
just a single line: print "hi"

here is the code for the __init.py:

import os
plugindir = os.path.split(__file__)[0]
for f in os.listdir(plugindir):
    f = os.path.split(f)[-1]
    if f.endswith('.py'):
        f = f.split('.')[0]
    try:
        exec('import %s'%f)
    except: pass


Now, if we import the plugins package, we can see module a, in the
output of dir:

In [1]:import plugins
hi

In [2]:dir(plugins)
Out[2]:
['__builtins__',
 '__doc__',
 '__file__',
 '__init__',
 '__name__',
 '__path__',
 'a',
 'f',
 'os',
 'plugindir']

best,

Flávio




More information about the Python-list mailing list