PyGI - Python dynamic bindings based on GObject-Introspection
Recently, PyBank, the runtime bindings generator based on GObjectIntrospection has been merged into PyGObject tree. As part of the Google Summer of Code 2009, Simon van der Linden extended the implementation (see his branch). More recently, due to its experimental status and in order to keep the development going while being able to package it easily, it has been decided to keep it as a separate module: PyGI.
Getting the code
For now it is suggested that PyGI is ran in a sanboxed environment. Best way to do that is with jhbuild.
follow Jhbuild build instructions until (including) jhbuild bootstrap
$ jhbuild build gtk+ pygi
To activate jhbuild environment, run jhbuild shell. After that the specific console session will make use of the sandbox and you will be able to use PyGI. Verify:
$ python import gi print gi.__file__
Note: If you choose to install pygi into your working environment instead of the sandbox, make sure that you have PyGObject compiled with the '--enable-pygi' flag.
Until better instructions are in place, the pygi-convert script will give you some idea of the currently required transformations.
The old and new bindings do not mix together well. Make sure that you don't have any "import gtk" lines in your code as that will cause stack overflow - replace them with the appropriate from gi.repository import ... lines.
The gi.repository module is a dummy module that installs an import hook which intercepts imports of dynamic modules and returns objects that implement the module protocol (see PEP 302).
The module objects are lazy. When an attribute is needed, a wrapper is constructed on-the-fly, whether it be an object (i.e. a constant), a class (an enumeration, a structure, an object, an interface, etc.), or a function. Class and instance attributes and methods are not lazily added. Object classes inherit from GObject, the signal and property-related methods in particular, and are constructed by a meta class that is a subclass of GObjectMeta, so subclassing in Python is no different.
Once a wrapper is constructed, it is registered in the type system, as any other PyGObject wrapper. Whenever an object needs to be wrapped (as a return value, for instance) and hasn't got a wrapper class yet, PyGObject will try to fetch its info from the GObjectIntrospection repository and get the wrapper by importing the class (through gi.repository's import hook, thus).
Although most of the code is written in C, import hooks, and meta classes are not. There are, in the gi module, a few bindings with GObjectIntrospection C API, thus. The most important wrapper is g_callable_info_invoke; it is in charge of marshalling.
Bugs and patches
Please file bug reports in Bugzilla. Thanks!