let us not mourn telepathy-python

But let us instead celebrate gobject-introspection.

While there has been no official announcement, I think it’s probably time we declared telepathy-python to have passed away. Deprecated. In the great attic of the sky.

The python-telepathy client-side bindings have been in a state of disrepair for a long time now, not able to do the heavy lifting that other bindings such as tp-glib and tp-qt4 have been focusing on.

telepathy-butterfly is not really maintained, isn’t supported properly by empathy master, and is looking to be replaced in the future by the MSN Live XMPP support. In the meantime bug #663829 migrates existing butterfly accounts to telepathy-haze. I’m not sure about telepathy-sunshine, but I suspect it also won’t work with the latest Empathy.

Through work I started, and a bunch of other people have continued, telepathy-glib client-side bindings have been growing increasingly more introspectable as time passes. This is now used by gnome-shell, and it works pretty well.

Since someone asked today, here’s how you set your global presence in Python:

from gi.repository import TelepathyGLib as Tp
from gi.repository import GObject

loop = GObject.MainLoop()
am = Tp.AccountManager.dup()
am.prepare_async(None, lambda *args: loop.quit(), None)
loop.run()

am.set_all_requested_presences(Tp.ConnectionPresenceType.AVAILABLE,
    'available', 'Set by script')

Unfortunately we can’t introspect the service-side bindings, they do some things that are very creative and clever, but that gobject-introspection just doesn’t understand. Which means you can’t write a CM using PyGObject yet. The solution, I think, is likely to come with a future, GVariant-based telepathy-glib, but I’m still trying to figure out how we can make things (like mixins) work in a way that g-i can understand.

mistakes with g_value_set_boxed()

In today’s PSA, mistakes with g_value_set_boxed(). A mistake that’s been made several times by yours truly, and only realised today thanks to Xavier.

At some point in the GLib 2.22 cycle, types such as GArray, GPtrArray, GByteArray and GHashTable1 gained ref() and unref() methods, which allowed things like g_boxed_copy() and g_boxed_free() to be a stack faster for those types. This was mid-2008.

Danni, who didn’t get the memo, had been occasionally writing bits of code like this:

GArray *array = g_array_new (...);

g_value_set_boxed (value, array);
g_array_free (array, TRUE);

Which, if you read the code, will keep the wrapper alive, so your code won’t crash, but will release all the data the array contains. Similarly for g_ptr_array_free() etc. It nicely zeros out the length of the array, so when you come to read it in your GValue, it looks empty.

The correct thing to do (of course) is unref your data, which will then free the memory and the wrapper when the refcount reaches zero.

GArray *array = g_array_new (...);

g_value_set_boxed (value, array);
g_array_unref (array);

Update: As pointed out in this simple example, you can replace this with the following pattern:

GArray *array = g_array_new (...);

g_value_take_boxed (value, array);

Which passes your ownership to the GValue. Where this falls down is for more complex values built for dbus-glib, where the ownership isn’t clear-cut, and so you need to free the components separately afterwards.

  1. You can discover what g_boxed_copy() and g_boxed_free() will do for a type by looking for its G_DEFINE_BOXED_TYPE in GLib, which is probably in gobject/gboxed.c. []