First of all, let me show you a screenshot showing what have been hacking on in my spare time over the last two weeks or so:
It’s showing a simple web browser written in python using WebKit, this is the code for that:
import Gtk, WebKit
win = Gtk.Window(Gtk.WindowType.TOPLEVEL)
p = WebKit.Page()
There are no specific bindings for WebKit, or even Gtk in this case. It’s all done using the introspection information available through gobject-introspection. I am not using the existing python bindings for GObject and GTK, I am instead using pybank, the python bindings for gobject-introspection.
The bank module, our interface to pybank differ from most (all?) GNOME language bindings written today by constructing the bindings in runtime. The bank module loads and interprets the metadata repository compiled using the g-idl-compiler tool. When you first access the Page class in WebKit it generates the Page class, and because it’s a GtkContainer subclass it imports the Gtk bindings and eventually the GObject ones as it’s also a subclass of GObject. When calling the constructors and methods it’s using libffi.
Before you’re all getting too excited, this is just a proof of concept, you won’t be able to build real applications based on pybank, you can’t even listen to signals yet. The only supported parameter types at the moment are int, str, enum and object. It’s mainly used a testcase for the introspection framework, to be able to make sure that the information available through introspection is going to work for this kind of language/binding.
The idea behind gobject-introspection is that each C library itself will generate and install the metadata at compile time. The metadata represents what you see in the C headers and a little bit extra which is already available through introspection in GObject such as properties, signals and class inheritence.
So what’s missing before we can start using this?
Jürg of Vala fame has written a header parser which will generate the metadata by scanning the headers. It’s in a pretty good state already, but not good enough to generate good enough metadata, it still needs to be tweaked a bit. The metadata in gobject-introspection needs a few additions such as typedefs, default values, a module/metdata mapping and a few other things.
In the screenshot attached below you can see that this is using about 6M of memory. Right, the bindings are not finished and the application is rather trivial, but I don’t expect this to go up significantly as I add more features for pybank, I expect it to go down as I can remove a couple of dependencies when gobject-introspection will be nearer to competition.
- Provide all information necessary to generate language bindings
- Consolidate this information, to avoid duplication between all languages
- Encourage upstream projects to include the metadata
This is the coolest thing I have seen in years. Well done Johan! Now hurry up and get it in production!
Oh my goodness. This is greatness beyond measure. Suddenly everything will be bound without having to wait…what help do you need, if any? Not that I expect that I’ll be able to do anything this cool!
Johan, this is excellent news!
Is this kewl or what?!
Keep us posted on this 🙂
Wow, I am really looking forward to writing future Gtk applications with pybank, that is soo cool!
That’s amazing. Instant python-bindings for all glib-based libraries? /Un/credible!
And this would also work for Ruby and other scripted programming languages? I’m blown away.
One small note here:
WebKit renders widgets as GTK+ widgets? Niiiiice 😀
Stuart: thanks for the offer but at the moment I don’t think there is a lot to do, it’s very early we need to define a stable api and add missing features. I’ll post an upcoming post when I need external help
Raphael: Not all languages are able to do this in runtime. However Ruby and Perl should be one of them.
Java/C#/C++/Vala etc won’t.
Henrique: Firefox is rendering forms as gtk widgets in 3.0 too.
Hi Johan. This is fantastic. This is surely a quicker way to build and maintainer python wrappers around C apis.
However, what do you think are the pros and cons of using gobject-introspection or pybank wrt building apps using python?
This is unbelievably awesome. I can’t wait until this can be used in real applications!
Great work, a really innovative idea
This sounds awesome. Thanks and please keep it up! 🙂 I tried to install gobject-introspection to test it, but I couldnt get it to build.
gcc -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -o .libs/g-idl-generate g_idl_generate-generate.o -Wl,–export-dynamic -pthread /usr/lib/libgobject-2.0.so /usr/lib/libgmodule-2.0.so /usr/lib/libgthread-2.0.so -lrt /usr/lib/libglib-2.0.so ./.libs/libgirepository.so -ldl
./.libs/libgirepository.so: undefined reference to `ffi_type_pointer’
./.libs/libgirepository.so: undefined reference to `ffi_type_float’
./.libs/libgirepository.so: undefined reference to `ffi_type_void’
./.libs/libgirepository.so: undefined reference to `ffi_type_sint64′
./.libs/libgirepository.so: undefined reference to `ffi_prep_cif’
./.libs/libgirepository.so: undefined reference to `ffi_type_uint32′
./.libs/libgirepository.so: undefined reference to `ffi_type_double’
./.libs/libgirepository.so: undefined reference to `ffi_call’
./.libs/libgirepository.so: undefined reference to `ffi_type_sint8′
./.libs/libgirepository.so: undefined reference to `ffi_type_uint8′
./.libs/libgirepository.so: undefined reference to `ffi_type_sint32′
./.libs/libgirepository.so: undefined reference to `ffi_type_uint16′
./.libs/libgirepository.so: undefined reference to `ffi_type_sint16′
./.libs/libgirepository.so: undefined reference to `ffi_type_uint64′
collect2: ld returned 1 exit status
make: *** [g-idl-generate] Error 1
Sorry…I just figured out the ffi problem. My bad 🙂