problem with hack using multiple inheritance for plugins

massimo s. devicerandom at gmail.com
Thu Jun 28 06:24:48 EDT 2007


Before all, I'm not a professional programmer but just a biophysics
ph.d. student, so if something makes you scream of horror, please
forgive me...

Ok, this is not straightforward at all.
I am working on an application that uses plugins. Plugins are coded as
small classes that become inherited by a main class ( a cmd.Cmd
actually) in the following way:

(see also this thread:
 http://groups.google.it/group/comp.lang.python/browse_thread/thread/4d6da027bb9249bd/0f95c60add4ef5ad
)

---
...     def do_this(self, arg):
...             print "THIS", arg
...
>>> class Bar:

...     def do_that(self, arg):
...             print "THAT", arg
...
>>> plugins = [Foo, Bar]
>>> def make_command_class(*bases):

...     return type(cmd.Cmd)("MyCli", bases + (cmd.Cmd,), {})
...
>>> cmd = make_command_class(*plugins)()
>>> cmd.cmdloop()

(Cmd) help

Undocumented commands:
======================
help  that  this

(Cmd) that one
THAT one
(Cmd)

-----------

And it works. Now I'm trying to do the same trick for another base
class, this time a WxPython frame.
Also in this case, "plugging" seem to work, but with an important
difference.

In the command line plugin API, I define a _plug_init() method that is
called in the main class __init__ . This for adding plugin-specific
initializiations.
That's what I do in the command line __init__:

       for plugin_name in self.config['plugins']:
            try:
                plugin=__import__(plugin_name)
                try:
                    print type(self)
                    eval('plugin.'+plugin_name
+'Commands._plug_init(self)')
                except AttributeError:
                    pass
            except ImportError:
                pass

And it works flawlessly.
Problem is, the exact same code when done using the wxFrame as the
baseclass, doesn't work:

            #make sure we execute _plug_init() for every command line
plugin we import
            for plugin_name in config['plugins']:
                try:
                    plugin=__import__(plugin_name)
                    try:
                        print type(self)
                        eval('plugin.'+plugin_name
+'Gui._plug_init(self)')
                        pass
                    except AttributeError:
                        pass
                except ImportError:
                    pass

with the following error:

Traceback (most recent call last):
  File "hooke.py", line 801, in <module>
    main()
  File "hooke.py", line 787, in main
    main_frame = make_gui_class(*GUI_PLUGINS)(None, -1, ('Hooke
'+__version__))
  File "hooke.py", line 308, in __init__
    eval('plugin.'+plugin_name+'Gui._plug_init(self)')
  File "<string>", line 1, in <module>
TypeError: unbound method _plug_init() must be called with
dummyguiplugGui instance as first argument (got MainWindowPlugged
instance instead)

The problem seems to be that if I call type(self) before doing the
eval('plugin... ) line:
- in the working case, I get type <type 'instance'>
- in the not working case, I get <class '__main__.MainWindowPlugged'>

At this point, it seems too much a deep object-oriented hell to be
able to dig it myself. Would you help me getting some cue on the
problem?

m.




More information about the Python-list mailing list