GNOME Bugzilla – Bug 538401
No consistent MRO for bases TreeModel, TreeDragSource
Last modified: 2010-11-07 03:28:27 UTC
This code: def find_child(container, path): if not path: return container for child in container.get_children(): if child.__class__.__name__ == path[0]: return find_child(child, path[1:]) return None fc = gtk.FileChooserDialog() path = ('VBox:FileChooserWidget:gtk.FileChooserDefault:' 'VBox:HPaned:VBox:ScrolledWindow:TreeView') view = find_child(fc, path.split(':')) print view.get_model() produces the following error: TypeError: Cannot create a consistent method resolution order (MRO) for bases TreeModel, TreeDragSource ** ERROR **: file /build/buildd/pygobject-2.14.0/gobject/pygobject.c: line 907 (pygobject_new_full): assertion failed: (tp != NULL) aborting... Avbruten (SIGABRT) It may be because ShortcutsPaneModelFilter is not wrapped. But that shouldn't make it crash either way.
Code crashes trying to create a wrapper for: - type: ShortcutsPaneModelFilter; - parent type: GtkTreeModelFilter; - interfaces: GtkTreeDragSource, GtkTreeModel; parent_type __mro__:(<type 'gtk.TreeModelFilter'>, <type 'gobject.GObject'>, <type 'gtk.TreeModel'>, <type 'gtk.TreeDragSource'>, <type 'gobject.GInterface'>, <type 'object'>) So, the problem here is that a couple of interfaces, TreeDragSource and TreeModel, are not only listed in the MRO of the base type but also being added explicitly in the new subtype. Thus, the best solution appears to be not to add interfaces as bases of leaf types if the main parent type already has those interfaces in MRO.
Created attachment 112771 [details] [review] patch
Gustavo: do we have a test case which can go into pygobject for this?
Gustavo: your patch doesn't work. You can test on the following code: import gobject import gtk class TestTreeModel(gtk.ListStore, gtk.TreeDragSource, gtk.TreeModel): pass Note that it fails before the type is registered with PyGObject (in this case it is actually not registered at all). As far as I understand, this is a normal interpreter behaviour and we cannot and shouldn't do anything about it. Except maybe instead of assert() we should raise proper Python exception.
To think, I was wrong. As I understand now, this is about wrapping C code, not subclassing in pure Python. Disregard last comment.
Created attachment 118466 [details] [review] test case This is a test case for bug as I understood it. Note that Gustavo's patch doesn't solve it. As far as I understand, we need to prune all bases that are already in base list _or_ have any subtype in the base list. Gustavo's patch contains only the first part of that condition. But please tell me if I misunderstood the bug. Kinda difficult without any tests or context.
What you are saying makes some sense and would point towards changing: if (PySequence_Contains(py_parent_type->tp_mro, (PyObject*) py_interface_type)) continue; With an interation loop and test using PyObject_IsSubclass(). However then I realize that, in theory, if your base type A has a type B which is subclass of C, then A's MRO should in principle contain all of A, B, and C, and so it would seem that the PySequence_Contains test ought to be enough. But, hey, it's worth a shot to try the for-IsSubclass loop and see if it makes any difference. (In reply to comment #6) > Created an attachment (id=118466) [edit] > test case > > This is a test case for bug as I understood it. Gah! No more GIO, please 8| GVFS doesn't want to work in a simple jhbuild environment without dbus hacks. :-(
This bug is almost 2 years old. is it still relevant?
Closing this bug report as no further information has been provided. Please feel free to reopen this bug if you can provide the information asked for. Thanks!