Introspection hackfest at the Boston Summit

Blogroll, GNOME, General, PyGTK, Python, olpc No Comments

We’re arranging an introspection hackfest at the Boston Summit! Thanks to the nice lads at the foundation we can have most of the participants flown over. Colin Walters, Jürg Billeter, Philip Van Hoof, I and hopefully Havoc Pennington is going to be there.

If you’re interested in language bindings or other uses of the introspection data, come by and help us out.

Oh, I almost forgot to say hi to Planet Python. Andrew was kind enough to add me there. My name is Johan Dahlin and I’m mostly working on Python related to GNOME, especially, Python bindings for GObject and Gtk., and Kiwi + Stoq of course. The introspection project is intended to make it easier to write language bindings for the Gnome stack, not only Python ones.

PyGObject activities

Blogroll, GNOME, General, PyGTK, Python, olpc 1 Comment

I’ve been spending quite a bit of time lately on PyGObject, the python bindings for GObject. This blog post will summarize the recent activies.

Code Generator move

One of the most important parts of the gtk python bindings lies within the code generator. This piece of software which was mostly written by James Henstridge, Gustavo Carneiro and I takes an API definition file (in scheme s-expression style) and output C glue which tell Python how to call the API in a library. For various reasons the code generator is mostly intended to be used by a GObject based library. It was originally written for PyGTK but has since been used in a number of other placs, most noticable gst-python contains a fork which various modifications. It has recently moved from the PyGTK package to PyGObject and can now easily be used by GObject based library which wishes to use it without depending on GTK+.

GIO

The principal motivation for moving the code generator from PyGTK to PyGObject was to be able to create GIO bindings. An initial set of bindings has been created for GIO. They are not complete yet, quite a bit of the API which takes async result parameters has not yet been written, but it should be perfectly usable by applications already. Please use it and let me know if there is any methods missing and I will gladly wrap them for you

GLib

One of the complaints over there years has been that it’s kind of weird to type gobject.MainLoop(), gobject.io_add_watch() etc, since these functions are not really related to GObject. Complain no more, they have now moved to a new module called just glib. It’s been quite hard to come up with any reasonable use cases for third party packages using glib but not gobject. I guess one of them is python bindings for Qt wishing to integrate with the python bindings for Gtk+. Qt already provides (optional) glib/mainloop integration, so perhaps this would be useful to them.

Porting to Python 3

This weekend I ported the glib and gobject modules over to be compilable against Python 3.0b2. It has been done in such a way that the source code is compatible with both the 2.x and 3.0 APIs of Python. To be able to do that I was forced to add a number of quite intrusive macros which takes care of the hard work. I’ve only managed to reach the point where it is possible to import the gobject module. The code generator and the gio bindings has not yet been ported. Even less has the testsuite been run, so this is just moderatly useful at this point. As part of porting this I had to make the python support in automake be compatible with python 3. Patches against git head of automake can be found here.

GIO python bindings

Blogroll, GNOME, General, PyGTK, Python, olpc 7 Comments

Late yesterday evening I did a new release of pygobject. The first one in about 10 months, I should do this more often I know. The most important thing featured in this release is the addition of GIO bindings. I know lots of you out there have been asking for this.

There’s still no official documentation included, but there’ll be in the near future as we have a couple of people working on it. While you wait, enjoy this simple example:

import gio
fp = gio.File("http://planet.gnome.org")
data = fp.read()
print data

We have also moved the code generator from PyGTK into PyGObject, this means that GObject bases libraries can be wrapped in python without having to depend on GTK+, this should be quite useful, I think.

I’d especially thank Paul Pogonyshev (doublep on irc) for this work on this release, he’s getting more and more involved in both PyGTK and PyGObject, thanks Paul!

Introduction to GObject Introspection

Blogroll, GNOME, General, PyGTK, Python, olpc 7 Comments
This was also sent to gtk-devel today:
== Introduction ==

GObject-introspection is a package which will collect and extend the API
metadata for GObject based libraries. The main motivation of this work is to
centralize all introspection information required to write a language binding.

There are many other use cases as well, some of them are described at:

   http://live.gnome.org/GObjectIntrospection/

== Current status ==

The GObject-Introspection module/tarball contains the following:

     * An XML format called GIR containing introspection information
     * python package to create and parse the GIR format
     * scanner to generate GIR format from C source and headers

These components are also included, but needs to be ported to the GIR format:

     * a typelib similar to xpcom/msole which stores the information
       on disk in a binary format
     * a compiler to compile the typelib from a xml format (and vice versa)
     * C library to read the typelib

A separate SVN module called gir-repository has been created.
The idea is to create .gir files of all libraries available in the
the whole stack which language bindings can depend on.
Eventually the plan is to move the .gir files into the upstream projects
themselves, but that’s likely to be a long process.

== GIR XML Format ==

The core of the GObject-introspection is an XML format which is called GIR (
GObject Introspection Repository) which contains the API introspection
metadata for a library or interface entity.

GIR currently contains three different XML namespaces:
  • core: contains features available in popular programming languages: classes, methods, functions, interfaces, properties, strings, enums etc.
  • c: contains features specific to the C language: identifiers, symbol names, C types
  • glib: contains features specific to GLib/GObject: signal, GType, flags, paramspec
The separation of different data in different namespaces allow you
to reuse it allows you to arbitrarily extend the metadata available
in different languages.

== Scanner ==

To be able to bootstrap the effort and make something which will be
available in a reasonable timeframe we’ve been working on a scanner
which parsers C sources and headers and extracts the metadata and
generates a GIR file.

This is likely to be used by most of the Gtk/GNOME stack, as it would
require the least amount of work, however it’s not the only way to
use the GIR format nor GObject-Introspection.
In the future we might use something similar to CORBA IDL to define
the interface, as GIR is not meant to human editable.

In addition to the parsing the C headers, additional metadata will
be provided, likely by using source annotations in gtk-doc comments.

== Typelib ==

To be able to create efficient read introspection data we need a typelib, eg
an efficent disk format with a C API to access the internal data.
Matthias wrote one based on the XPCOM typelib which has not yet been
updated to the GIR format, it’s instead the tools to compile it are still
using an older XML format.

The work on finishing the typelib is depending on having the GIR format
somewhat stable and at that point updating the existing tools to understand it.

== How can I help? ==

At this point I’d like to get more eyes at the current GIR format to make
sure that it contains the necessary information and in a way which will
be easy to parse/access.
I am currently working mainly on the scanner to be able to quickly get
a large amount API expressed in GIR files.

For more information, check out the wiki page:

   http://live.gnome.org/GObjectIntrospection/

And the gobject-introspection and gir-repository modules in GNOME SVN.

Enough wakeups in Python programs

Blogroll, GNOME, General, PyGTK, Python, olpc 3 Comments

Yesterday I released two new releases of PyGObject and PyGTK. The most important change in both of releases is the support of a new API, available only in the svn version of Python which will prevent gobject and gtk from waking up once every 100 ms.

This should allow the CPU to be idle longer and thus save battery life, for your desktop and for children.

I would like to thank Guido van Rossum, Adam Olsen and Gustavo Carneiro for making sure that Python has enough support for this to be possible.

Unfortunately, it will take some time before this is widely used because it will only be included in Python 2.6. However, for OLPC the best option is probably to apply the patch from python issue 1583. Perhaps Linux distributors could do the same?

Future of GNOME language bindings

Blogroll, GNOME, General, PyGTK, Python, olpc 13 Comments

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:

.WebKitGtkPython.png

It’s showing a simple web browser written in python using WebKit, this is the code for that:

import bank
import Gtk, WebKit

win = Gtk.Window(Gtk.WindowType.TOPLEVEL)
p = WebKit.Page()
p.open(”http://www.google.com/”)
win.add(p)
win.show_all()

Gtk.main()

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.

GObject-introspection goals:

  • Provide all information necessary to generate language bindings
  • Consolidate this information, to avoid duplication between all languages
  • Encourage upstream projects to include the metadata

ObjectList tutorial

Blogroll, GNOME, General, PyGTK, Python, olpc 4 Comments

This blog post will give you an introduction to the ObjectList widget which is a part of the kiwi library.

* Rationale

Creating graphical user interfaces which displays a sequence of objects is a common task. In the GTK+ toolkit you will normally use a GtkTreeView for this. GtkTreeView is a very flexible and extensible widget, for instance it allows you to separate the data storage from the representation. However the disadvantage of using the GtkTreeView is that it’s a little bit too complicated to use, especially for beginners.

The ObjectList aims to provide a familiar API to create, manipulate and access sequences of objects. It builds on top of GtkTreeView, and allows you to access the “raw” objects (view, columns, model, cellrenderers, selection) in case you want to do something which is not directly supported by the ObjectList.

Kiwi and ObjectList are tied to the Python programming language and depends heavily on PyGTK (and thus CPython). However the concepts introduced in the widget are usually not specific to Python, it’s very possible to implement similar high level wrappers on top of GtkTreeView for C#, Java etc.

* Simple ObjectList example

Here is the source code and the output of a simple ObjectList example

Simple ObjectList example Simple example screenshot

Let’s walk through the example and explain what it does.

  • The class Fruit is defined with two attributes; name and price.
  • An ObjectList called fruits is created which has two columns, name and price
  • 5 objects are created and inserted into the list.

The example is concluded by creating a PyGTK window, adding the objectlist to it and running the main loop.
The data displayed in the ObjectList is stored in normal python instances, there is no need to create and set column types for a GtkTreeModel and extract the data from your python objects and insert it into the model. The model / view separation is kept while still keeping it easy to use.

Notice that the data is appended to the list by calling the append() method of the ObjectList, this is intentionally similar to the append method of the builtin list type of python. If you wanted you could use the extend() method to insert a list of object at one go.

The objects inserted into the list can be modified by using standard python list concepts:

  • iteration: for item in list
  • accessing an individual item: list[n]
  • removing an item: del list[n] or list.remove(item)
  • accessing parts of the item: list[n:m]

There are also methods beyond a normal python list routines which only makes sense in graphical interfaces:

  • selecting an item: list.select(item)
  • getting the selected item: list.get_selected()
  • changing the columns: list.set_columns(columns)
  • getting the columsn: list.get_columns()
  • etc…

* Columns

When you create a column you define how the data is going to be displayed. Column width, sorting, justification, markup and so on. Here is an incomplete list of the support column attributes:

  • title: the text will be used in the column header
  • justify: the justification, eg left or right aligned
  • format: printf style format string
  • width: width in pixels of the column
  • sorted: if we should sort the data after the content in this column
  • editable: is the column editable?
  • use_markup: should the content be interpreted as markup?
  • use_stock: treat the content as stock icon names and display icons

Here is a more complicated, real world example from Stoq, a Retail Management System written on top of Kiwi.

Accounts payable column definition

Accounts payable

The interface shows the accounts payable application which lists outgoing payments.

What we can see from the screenshot is:

  • The first column is sorted and it has the title “#”
  • The third column is the supplier name which is a bit too wide to fit and uses ellipsize
  • The fourth column is the date the purchase was sold and is formatted according to the current locale
  • The last column uses the special datatype currency which formats a number according to the monetary rules defined for the current locale, with thousand separators, decimal points and currency symbols set right.

This is all for now, for more information about Kiwi check out Howto, the API reference and the source code repository

Valgrind & Andvare

Blogroll, GNOME, General, PyGTK, Python 8 Comments

Yesterday I on a bus ride from São Paulo I had the opportunity to see some of the developments tools available on OSX. Shark and mallocdebug are quite interesting, bling-bling for the developer masses.

When I woke up this morning I realized that it shouldn’t be too difficult to do something similar on top of valgrind.

[…later in the evening and 500 lines typed down…]

andvare.png

It’s quite useful already, it groups all the leaks by the topmost function which is a bit easier to follow than the output valgrind usually gives us.

You can find a tarball here if you want to play around with it.

Update: I uploaded a bzr branch to launchpad:

bzr branch http://code.launchpad.net/~jdahlin/andvare/main/

GtkBuilder has landed!

Blogroll, GNOME, General, olpc 15 Comments

Today, after more than 2 years and 120 comments I could finally close #172535, adding support for loading interfaces created by UI designers in Gtk+.

GtkBuilder replaces libglade, it uses a similar XML format but also supports the following:

  • GtkTreeViews including columns and cell renderers
  • Menus and toolbars created using GtkUIManager, including actions & actiongroups.
  • TreeModels, it’s possible to define the data used by treemodels. It’s used by treeviews, iconviews, comboboxes, and entries.
  • SizeGroups, align all these widgets without using tables!

I’d like to especially thank Matthias Clasen for reviewing the beast, it was over 6500 lines in the end! Henrique Romano helped me to implement parts of it and Tristan Van Berkom, Tim Janik, Kalle Vahlman, Christian Perch, Dan Winship, Owen Taylor, Behdad Esfahbod and Havoc Pennington also helped out with suggestions and improvements to the patch.There are a couple of things that needs to be done to simplify the transition from libglade to gtkbuilder though:

  • Add support in UI designers. Gazpacho mostly supports it already, it’ll be easy to fix. glade-2 is out of the question and I expect glade-3 to at least partially support GtkBuilder before GNOME 2.20 is released
  • Improve migration from libglade files. There’s a script in bugzilla which converts old libglade files to files which gtkbuilder can load. It needs to be improved and tested, especially menus and toolbars
  • Some libglade features are not supported yet, such as loading only a part of a glade file and pixbuf properties. These will be fixed before the final Gtk+ 2.12 release

Now, time to party!