GNOME Bugzilla – Bug 664871
PyGTK segfaults if imported after gobject-introspection
Last modified: 2011-11-28 16:42:13 UTC
The following steps cause a segfault (I can attach a core dump if you can't reproduce it): >>> from gi.repository import Gtk >>> import gtk /usr/lib/python2.7/dist-packages/gobject/constants.py:24: Warning: g_boxed_type_register_static: assertion `g_type_from_name (name) == 0' failed import gobject._gobject /usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:40: Warning: specified class size for type `PyGtkGenericCellRenderer' is smaller than the parent type's `GtkCellRenderer' class size from gtk import _gtk /usr/lib/python2.7/dist-packages/gtk-2.0/gtk/__init__.py:40: Warning: g_type_get_qdata: assertion `node != NULL' failed from gtk import _gtk Segmentation fault Now, I realize that doing this may seem strange; I do have a reason though. My use case is Twisted, a Python networking libraries. Twisted supports multiple event loop drivers, e.g. select(), epoll() and also gtk2, and runs many of its tests multiple times, once with each event loop, *within the same process*. A developer can thus be assured the tests run with multiple event loops without having to run the test suite multiple times. Python C modules are typically opened with dlopen() in RTLD_LOCAL mode, so in theory there shouldn't be symbol clashes if the two Python libraries link against different C libraries. When I added a test python gi event loop, I naturally tried to do the same, but apparently having both libraries in the same process does not work. It's unclear of course who should have to fix this, but the opposite import order just results in an error, not a segfault. Still not ideal, but better. This is Ubuntu 11.10, python-gobject 3.0.0-0ubuntu4 and python-gtk2 2.24.0-2.
(It's possible this is Ubuntu specific, they have something called "python-gobject-2 2.28.6-6svn1: deprecated static Python bindings for the GObject library" which sounds suspicious, so if this is unreproducable on other platforms I'll refile a bug with them.)
I can confirm this on gentoo... Is there any way of using gobject (for gtk3) after some other module has already imported gtk (for gtk2)?
Mixing static bindings (PyGTK, PyGST, PyWebKitGtk, ...) with introspected bindings ("from gi.repository import Gtk, Gst, ...") in the same process is not a good idea. Further, there's a good chance "from gi.repository import Gtk" will load GTK+ 3 (although you're never sure unless you "gi.require_version('Gtk', '3.0')") while "import gtk" loads GTK+ 2. Loading multiple major versions of a library like GTK+ in the same process is not supported. See the "Prevent mixed linkage" here: http://developer.gnome.org/gtk3/3.2/ch25s02.html I'm afraid you'll have to add a new event loop driver to Twisted that uses the introspected bindings offered by PyGObject 3 before you'll be able to use Twisted together with GTK+ 3.
The issue isn't adding a new driver, it's more loading two into same process for testing purposes only. But if it's not supported we'll have to find some other way to run automated tests.
It isn't supported because each use GLib 2.x and will stomp on the type system. The issue happens when we create wrappers for GObject classes. Wrappers are mapped from the GObject type to the python wrapper. Since both PyGTK and PyGObject create different wrappers for the same type it becomes a race condition on which wrapper you will get. Since both export different API's you will end up eventually calling an API that doesn't exist or has a different signature. There is also a race condition when creating new types for derived classes. In any case there is no real way to make them run in parallel within the same process space.