(Update: Link to Tomeu s blog post, repost for
planet.gnome.org)
Last week I was in Prague to attend the
GNOME/Python 2011 Hackfest for gobject-introspection, to which Tomeu Vizoso kindly invited me after I
started working with PyGI some months ago. It happened at a place called
brmlab which was quite the right environment for a bunch of 9 hackers: Some comfy couches and chairs, soldering irons, lots of old TV tubes, chips, and other electronics, a big Pirate flag, really good Wifi, plenty of Club Mate and Coke supplies, and not putting unnecessary effort into mundane things like wallpapers.
It was really nice to get to know the upstream experts John (J5) Palmieri and Tomeu Vizoso (check out
Tomeu s blog post for his summary and some really nice photos). When sitting together in a room, fully focussing on this area for a full week, it s so much easier to just ask them about something and getting things done and into upstream than on IRC or bugzilla, where you don t know each other personally. I certainly learned a lot this week (and not only how great Czech beer tastes
)!
So what did I do?
Application porting
After already having ported four Ubuntu PyGTK applications to GI before (
apport,
jockey,
aptdaemon, and
language-selector),
my main goal and occupation during this week was to start porting a bigger PyGTK application. I picked
system-config-printer, as it s two magnitudes bigger than the previous projects, exercises quite a lot more of the GTK GI bindings, and thus also exposes a lot more GTK annotation and pygobject bugs. This resulted in a new
pygi s-c-p branch which has the first 100 rounds of test, break, fix iterations. It now at least starts, and you can do a number of things with it, but a lot of functionality is still broken.
As a kind of finger exercise and also to check for how well pygi-convert works for small projects now, I also
ported computer-janitor. This went really well (I had it working after about 30 minutes), and also led me to finally
fixing the unicode vs. str mess for GtkTreeView that you got so far with Python 2.x.
pygobject and GTK fixes
Porting system-config-printer and computer-janitor uncovered a lot of opportunities to
improve pygi-convert.sh, a big perl -e kind of script to do the mechanical grunt work of the porting process. It doesn t fix up changed signatures (such as adding missing arguments which were default arguments in PyGTK, or the ubiquitous user_data argument for signal handlers), but at least it gets a lot of namespaces, method, and constant names right.
I also fixed three
annotation fixes in GTK+. We also collaboratively reviewed and tested
Pavel s annotation branch which helped to fix tons of problems, especially after Steve Fr cinaux s excellent
reference leak fix, so if you play around with current pygobject git head, you really also have to use the current GTK+ git head.
Speaking of which, if you want to port applications and always stay on top of the pygobject/GTK development without having to clutter your package system with make install s of those, it works very well to have this in your ~/.bashrc:
export GI_TYPELIB_PATH=$HOME/projects/gtk/gtk:$HOME/projects/gtk/gdk
export PYTHONPATH=$HOME/projects/pygobject
Better GVariant/GDBus support
The GNOME world is moving from the old dbus-glib python bindings to GDBus, which is integrated into GLib. However, dbus-python exposed a really nice and convenient way of doing D-Bus calls, while using GDBus from Python was hideously complicated, especially for
nontrivial arguments with empty or nested arrays:
from gi.repository import Gio, GLib
from gi._gi import variant_type_from_string
d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
'/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)
vb = GLib.VariantBuilder()
vb.init(variant_type_from_string('r'))
vb.add_value(GLib.Variant('s', 'test'))
vb.add_value(GLib.Variant('u', 1))
vb.add_value(GLib.Variant('s', 'gtk-ok'))
vb.add_value(GLib.Variant('s', 'Hello World!'))
vb.add_value(GLib.Variant('s', 'Subtext'))
# add an empty array
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('as'))
vb.add_value(eavb.end())
# add an empty dict
eavb = GLib.VariantBuilder()
eavb.init(variant_type_from_string('a sv '))
vb.add_value(eavb.end())
vb.add_value(GLib.Variant('i', 10000))
args = vb.end()
result = notify.call_sync('Notify', args, 0, -1, None)
id = result.get_child_value(0).get_uint32()
print id
So I went to making the GLib.Variant constructor work properly with
nested types and
boxed variants, adding
Pythonic GVariant iterators and indexing (so that you can treat GVariant dictionaries/arrays/tuples just like their Python equivalents), and finally a
Variant.unpack() method for converting the return value of a D-Bus call back into a native Python data type. This looks a lot friendlier now:
from gi.repository import Gio, GLib
d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
'/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)
args = GLib.Variant('(susssasa sv i)', ('test', 1, 'gtk-ok', 'Hello World!',
'Subtext', [], , 10000))
result = notify.call_sync('Notify', args, 0, -1, None)
id = result.unpack()[0]
print id
I also prepared another patch in
GNOME#640181 which will provide the icing on the cake, i. e. handle the variant building/unpacking transparently and make the explicit call_sync() unnecessary:
from gi.repository import Gio, GLib
d = Gio.bus_get_sync(Gio.BusType.SESSION, None)
notify = Gio.DBusProxy.new_sync(d, 0, None, 'org.freedesktop.Notifications',
'/org/freedesktop/Notifications', 'org.freedesktop.Notifications', None)
result = notify.Notify('(susssasa sv i)', 'test', 1, 'gtk-ok', 'Hello World!',
'Subtext', [], , 10000)
print result[0]
I hope that I can get this reviewed and land this soon.
Thanks to our sponsors!
Many thanks to the
GNOME Foundation and
Collabora for sponsoring this event!