I'm looking into using gobject's OO framework for the low-level portion of an application, with the intention of using Python for extending and scripting the low-level functionality. Ideally, the C code would just use gobjects and know nothing (or as little as possible) about Python.
While studying PyGobject I stumbled into a subclassing problem. I'd like to subclass from Python a gobject class written in C (and itself derived from GObject), and eventually pass its instances to the C code that expects regular gobjects. This would allow Python code to create first-class GObject classes and objects usable within the framework. For example: # MyClass is a gobject class implemented in C. MyClass = gobject.type_from_name('MyClass') # Subclass it in Python. class Foo(MyClass): ... additional code here ... gobject.type_register(Foo) # From this point, instances of Foo should be GObject type instances # and therefore first-class citizens in the GObject world. Let's try it: [~/work/testgobject]$ python Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02) [GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2 [...] >>> import gobject >>> import ctypes >>> ctypes.cdll # load a pure-C SO that implements a test gobject type, DateTimeType >>> x=ctypes.cdll.LoadLibrary("./x.so") >>> x.initialize() # set up the type >>> gobject.type_from_name("DateTimeType") <GType DateTimeType (135936872)> >>> o=gobject.new(gobject.type_from_name('DateTimeType')) >>> o <__main__.DateTimeType object (DateTimeType) at 0xb7d8ac84> That part works -- the gtype is accessible from Python and appears usable. But what if I want to subclass the type? Since Python 2.4 allows subclassing built-in types, I tried it this way: >>> class Foo(gobject.type_from_name("DateTimeType")): ... def foo(self): ... self ... Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: Error when calling the metaclass bases GType.__init__() takes exactly 1 argument (3 given) Obviously, this is wrong. It doesn't make sense to try to subclass the GType type, we must inherit from a type that can create actual GType instances. The distinction is subtle, but very important, as shown here: >>> gobject.type_from_name('GObject') <GType GObject (80)> # (1) >>> gobject.type_from_name('DateTimeType') <GType DateTimeType (135936872)> # (2) >>> gobject.GObject <type 'gobject.GObject'> # (3) To inherit from DateTimeType, I need to get a Python type object like (3), not a GType type object, like (1) or (2). But hey, I already have a Python *instance* of DateTimeType, so the type must be accessible as well: >>> type(o) <class '__main__.__main__.DateTimeType'> If it's a class object, it must be subclassable: >>> class Foo(type(o)): ... def foo(): ... return self ... >>> foo=Foo() >>> foo <Foo object (DateTimeType) at 0xb7d8fd74> But Foo is still not a separate GObject class; for GObject code, a Foo object is indistinguishable from a DateTimeType object: >>> gobject.type_name(type(foo)) 'DateTimeType' To fix that, we must register it with GType: >>> gobject.type_register(Foo) <class '__main__.Foo'> >>> gobject.type_name(type(foo)) '__main__+Foo' Instances of Foo are now not only first-class citizens of the GObject world, but GObject is also aware of the inheritance relationship between DateTimeType and Foo: >>> gobject.type_children(gobject.type_from_name('DateTimeType')) [<GType __main__+Foo (136049464)>] In conclusion, it would seem that PyGTK's gobject wrapper has all the pieces needed for this, with the following parts being (to me) non-obvious: 1. What is the canonical way to convert <GType x> to something like <class 'x'> as shown above? Creating an instance of x and calling type(x) seems like an incredible kludge. 2. Has anyone tried to pass GObjects created in a similar way back to C? How does one convert a PyObject* to a GObject*? 3. Is it intended to be able to subclass gobject classes other than GObject? All the examples I can find only demonstrate subclassing gobject.GObject and its Python class children. I would appreciate any help with this. If this is described in a publicly accessible document, feel free to point it out. _______________________________________________ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/