Re: plugin development best practices

Discussion in 'Python' started by Jean-Paul Calderone, Feb 22, 2007.

  1. On Thu, 22 Feb 2007 15:36:42 +0100, "Diez B. Roggisch" <> wrote:
    >> Simple plugin system proposal:
    >>
    >> have a package (directory with __init__.py) called plugins where the
    >> actual plugins are modules in this directory.
    >>
    >> When the main script imports the plugins package, all plugin modules
    >> would be available as plugins.pluginA, plugins.pluginB , etc.
    >>
    >> A registry of available plugins would be available as a simple
    >> dir(plugins).
    >>
    >> code in the main script than wished to use a given plugin, would only
    >> have to look in the registry before calling any code from a given
    >> plugin.
    >>
    >> What is wrong/missing with this simple framework?

    >
    >Nothing wrong.


    Are you sure?

    exarkun@charm:~$ mkdir someplugins
    exarkun@charm:~$ touch someplugins/__init__.py
    exarkun@charm:~$ touch someplugins/a.py
    exarkun@charm:~$ python
    Python 2.4.3 (#2, Oct 6 2006, 07:52:30)
    [GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import someplugins
    >>> dir(someplugins)

    ['__builtins__', '__doc__', '__file__', '__name__', '__path__']
    >>>


    Hey, where's my plugin?

    This most trivial test would have demonstrated the problem with the proposed
    plugin system. But I suppose it was easier for Flavio to make someone else
    find the defect in his new system than to either test it himself or to look
    carefully at any of the existing systems.

    Jean-Paul
     
    Jean-Paul Calderone, Feb 22, 2007
    #1
    1. Advertising

  2. Jean-Paul Calderone wrote:

    > On Thu, 22 Feb 2007 15:36:42 +0100, "Diez B. Roggisch"
    > <> wrote:
    >>> Simple plugin system proposal:
    >>>
    >>> have a package (directory with __init__.py) called plugins where the
    >>> actual plugins are modules in this directory.
    >>>
    >>> When the main script imports the plugins package, all plugin modules
    >>> would be available as plugins.pluginA, plugins.pluginB , etc.
    >>>
    >>> A registry of available plugins would be available as a simple
    >>> dir(plugins).
    >>>
    >>> code in the main script than wished to use a given plugin, would only
    >>> have to look in the registry before calling any code from a given
    >>> plugin.
    >>>
    >>> What is wrong/missing with this simple framework?

    >>
    >>Nothing wrong.

    >
    > Are you sure?


    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)

    Diez
     
    Diez B. Roggisch, Feb 22, 2007
    #2
    1. Advertising

  3. Jean-Paul Calderone

    Paul Boddie Guest

    On 22 Feb, 16:13, "Diez B. Roggisch" <> 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
     
    Paul Boddie, Feb 22, 2007
    #3
  4. Jean-Paul Calderone

    Flavio Guest

    On Feb 22, 2:04 pm, "Paul Boddie" <> wrote:
    > On 22 Feb, 16:13, "Diez B. Roggisch" <> 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
     
    Flavio, Feb 22, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin Spencer
    Replies:
    2
    Views:
    471
    John Saunders
    Aug 6, 2003
  2. Amelyan
    Replies:
    2
    Views:
    501
    Steve C. Orr [MVP, MCSD]
    Apr 30, 2005
  3. Kevin Frey

    Best Practices for Web App Development ?

    Kevin Frey, Feb 3, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    495
    Raymond
    Feb 3, 2006
  4. Flavio
    Replies:
    8
    Views:
    315
    Flavio
    Feb 22, 2007
  5. Intransition

    Plugin best practices

    Intransition, Jun 15, 2011, in forum: Ruby
    Replies:
    5
    Views:
    470
    Intransition
    Jun 16, 2011
Loading...

Share This Page