GNOME Bugzilla – Bug 447271
gobject has a weird bug on mac. Involves python, property and subclassing gtk.Widget
Last modified: 2007-06-17 16:26:56 UTC
Steps to reproduce: 1. sublcass gtk.Widget to create two minimal widgets 2. in one of the widgets, create a property 3. gobject.type_register them 4. create an instance for both widgets 5. pass widget B as the parameter to property in widget A 6. run it and watch it crash, mac only! Stack trace: python umitInventory/new-sample/tests/test666b2.py GLib-GObject-ERROR **: file gobject.c: line 1625 (toggle_refs_notify): assertion failed: (tstack->n_toggle_refs == 1) aborting... Abort trap Other information: minimal sample: import gtk import gobject from gtk import gdk class A(gtk.Widget): def __init__(self): gtk.Widget.__init__(self) def _get_color(self): return self.__color def _set_color(self, color): self.__color = color def do_realize(self): self.set_flags(self.flags() | gtk.REALIZED) self.window = gdk.Window(self.get_parent_window(), width=self.allocation.width, height=self.allocation.height, window_type=gdk.WINDOW_CHILD, wclass=gdk.INPUT_OUTPUT, event_mask=self.get_events() | gdk.EXPOSURE_MASK) self.window.set_user_data(self) self.style.attach(self.window) self.style.set_background(self.window, gtk.STATE_NORMAL) self.window.move_resize(*self.allocation) def do_unrealize(self): self.window.set_user_data(None) def do_size_request(self, requisition): requisition.width = 40 requisition.height = 100 def do_size_allocate(self, allocation): self.allocation = allocation if self.flags() & gtk.REALIZED: self.window.move_resize(*allocation) def do_expose_event(self, event): cr = self.window.cairo_create() cr.rectangle(*event.area) cr.clip() cr.rectangle(*event.area) cr.set_source_rgb(1, 1, 0) cr.fill() badprop = property(_get_color, _set_color) gobject.type_register(A) class B(gtk.Widget): def __init__(self): gtk.Widget.__init__(self) def do_realize(self): self.set_flags(self.flags() | gtk.REALIZED) self.window = gdk.Window(self.get_parent_window(), width=self.allocation.width, height=self.allocation.height, window_type=gdk.WINDOW_CHILD, wclass=gdk.INPUT_OUTPUT, event_mask=self.get_events() | gdk.EXPOSURE_MASK) self.window.set_user_data(self) self.style.attach(self.window) self.style.set_background(self.window, gtk.STATE_NORMAL) self.window.move_resize(*self.allocation) def do_unrealize(self): self.window.set_user_data(None) def do_size_request(self, requisition): requisition.width = 100 requisition.height = 100 def do_size_allocate(self, allocation): self.allocation = allocation if self.flags() & gtk.REALIZED: self.window.move_resize(*allocation) def do_expose_event(self, event): cr = self.window.cairo_create() cr.rectangle(*event.area) cr.clip() cr.rectangle(*event.area) cr.stroke() gobject.type_register(B) class win(gtk.Window): def __init__(self): gtk.Window.__init__(self) box = gtk.HBox() a = A() b = B() a.badprop = b box.add(b) box.add(a) self.add(box) self.connect('delete-event', lambda x,y:gtk.main_quit()) if __name__ == "__main__": w = win() w.show_all() gtk.main()
Not Mac specific. Likely PyGObject bug.
Created attachment 90148 [details] minimal test case The problem is that pygobject_switch_to_toggle_ref is being called twice, both times from pygobject_setattro. It happens because in this case pygobject_setattro ends up recursively calling itself, and both the inner and outer pygobject_setattro invocations see the instance dictionary being created and call pygobject_switch_to_toggle_ref.
Committed revision 677.