After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 664871 - PyGTK segfaults if imported after gobject-introspection
PyGTK segfaults if imported after gobject-introspection
Status: RESOLVED NOTABUG
Product: pygtk
Classification: Bindings
Component: general
2.24.x
Other Linux
: Normal major
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2011-11-26 13:55 UTC by itamar
Modified: 2011-11-28 16:42 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description itamar 2011-11-26 13:55:55 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.
Comment 1 itamar 2011-11-26 14:01:19 UTC
(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.)
Comment 2 Tiago de Paula Peixoto 2011-11-26 18:43:25 UTC
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)?
Comment 3 Dieter Verfaillie 2011-11-26 22:06:18 UTC
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.
Comment 4 itamar 2011-11-26 23:33:21 UTC
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.
Comment 5 johnp 2011-11-28 16:42:13 UTC
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.