[pygtk] How to write a python plugin ?

Sébastien Granjoux seb.sfo at free.fr
Tue May 8 16:24:55 WST 2007


Hi All,

I have a C program using GTK which is already able to load C plugin 
using GModule and GTypeModule of glib.

Basically, I'm reading an ascii file to know what is the name of the 
type implemented in the plugin library. It should derivate from a common 
Plugin type. I'm calling a registration function in the plugin library 
to register this new type using g_type_module_register_type. Then, I can 
create new object of this type as needed.

The Plugin type has an activate and deactivate virtual method that must 
be implemented in the plugin code.


I have tried several ways to do this for a plugin written in python but 
I haven't found any solution yet.

I have created some python bindings for the Plugin type and I have 
written in python a first plugin like this:

import mylib

class MyPlugin(mylib.Plugin):

         def __init__(self):
                 print "Initialize MyPlugin"
                 super(MyPlugin, self).__init__()

         def activate(self):
                 print "Activate MyPlugin"

         def deactivate(self):
                 print "Deactivate MyPlugin"


1. My first try was the following:
I have written in C a python plugin class (PythonPlugin derivated from 
the Plugin class) which wraps a python object and forward call of 
activate and deactivate to it.

This class knows the python type: I'm searching for a type derivating 
from mylib.Plugin in all locals objects and keep it as a class data. The 
class is registered using g_type_module_register_type with the name of 
the python class when the python plugin is loaded.

The python object is created when a new instance of this class is needed 
using a code like:

static void python_plugin_init (PythonPlugin *object)
{
     PythonPluginClass *klass = (PythonPluginClass*) (((GTypeInstance*) 
object)->g_class);

     object->instance = PyObject_CallObject (klass->type, NULL);
}

This is almost working, the problem is that there is two Plugin 
instances. One is the base of PythonPlugin C class and the other 
instance is the base of the MyPlugin python class. It has been created 
by the pygobject stuff due to the call of "super(MyPlugin, self).__init__()"


2. I have tried to avoid create the PythonPlugin C class. As the 
pygobject library create bindings for my Plugin class, it's perhaps not 
needed.

The problem here is that it seems that pygobject can register only 
static type using pygobject_register_class which called 
g_type_register_static.

There is a pyg_type_register_custom_callback which could be perhaps 
useful in my case, but I haven't found enough documentation about it so 
I don't know how to use it.


3. Another solution is to avoid creating a new Plugin object from the 
python code. So I have rewritten the instance init function like the 
following:

static void python_plugin_init (PythonPlugin *object)
{
     object->instance = pygobject_new (G_OBJECT(object));
}

As far as I see, it wraps my PythonPlugin object correctly but It 
doesn't make the link with the implementation in python: the activate 
function in python is not called. It's a bit expected as I haven't use 
the PyObject type of the python implementation MyPlugin.

pygobject_new is calling PyObject_GC_New which should be equivalent to 
PyObject_New. It is not exactly the same than PyObject_CallObject 
though, so perhaps there is something else to do, I'm still searching.

Regards,

Sébastien


More information about the pygtk mailing list