GNOME Bugzilla – Bug 622987
Can't insert a Python dict into a GtkTreeStore
Last modified: 2010-11-12 15:46:33 UTC
An operation that used to work with PyGTK, I have a GtkTreeStore with a column of type PyObject. Appending a row containing a dict errors: the call to set_value in the TreeStore.append override now throws the error: "TypeError: argument 3: Must be of a known GType, not dict". Apparently this worked before the tree view overrides landed.
This should work now that I use the internal method for converting python types to GTypes. Can you confirm?
I can't test it at the moment, as libpeas hasn't been updated to follow the latest gobject-introspection changes, which are required for PyGObject to build (GIArgument rename). Once that's all sorted, I'll give it a test. Thanks!
It doesn't appear to be working using pygobject master (269ff8564eeb597dc06c27e293354b7ff7a71a82): Traceback (most recent call last):
+ Trace 223797
self.add_treeview_item(treeview, album)
[album, album['image'], title, dur, tip]
self.set_value(treeiter, i, row[i])
return info.invoke(*args)
jamendo.py:266–268 (http://git.gnome.org/browse/totem/tree/src/plugins/jamendo/jamendo.py#n266): parent = treeview.get_model().append(None, [album, album['image'], title, dur, tip] ) where "album" is a dict.
It seems that all *store only accept exactly the defined type, but not any type that inherit from it. If you use Gtk.ListStore(object) it will only accept object types, but nothing else, where it actually should accept all Python types.
I see, this comes down to the strict type checking we do. I'm looking into this.
The issue is pyg_type_from_object. Is it safe to return PY_TYPE_OBJECT for anything? I mean everything is a PyBaseObject_Type at the end of the day so this will remove a level of error checking. At issue is PyGtk does its own pointer checking using GValues while we use the generic parameter checking algorithm. Looking into it more
We lose here. In PyGTK the type checking happens in the override and then a GValue is passed without further checking. The problem we have is in the generic case we have no context on what that GValue should be. By returning a PY_TYPE_OBJECT for anything that passes through we start to hit asserts in the tests which crash them. The only way I see us fixing this is being able to send in GValues which are checked in the overrides and just passed through. I however feel that this opens us up to some potential bugs. The workaround on the app side is to create a wrapper gobject class which you used to wrap any python objects before sending them into a store. I'll see if I can at least get dictionaries and lists working.
I have come to the conclusion that checks for GValue are inane as there is little context to make the right decisions. They are like Python interfaces, anything goes, you need to check the inputs yourself. The best option would be to register a type checking function in the overrides for any interface that takes a GValue. If it is not registered, it shouldn't be able to be called or should use the current limited check. I'll see if I can whip that up tomorrow.
Created attachment 172200 [details] [review] [gi] make parameter check less strict when dealing with GValue params * Some GValue API can store a pointer to a python object for later use but our parameter checking was too strict to allow this * Add pyg_type_from_object_full API which takes a strict boolean and returns PY_TYPE_OBJECT if no other GType can be found * Since we don't have enough info to genrically check GValue parameters use the less strict type guessing when encountering a GValue param * Other API stays the same and continues to do strict testing
Please see if this fixes your issues. We still need to add checks to the override.
Created attachment 172214 [details] GDB log With the patch applied I can no longer import gst. python -c "import gst" results in a segfault, gdb output is attached.
Did you recompile the python-gst? I think I changed the ABI. I might need to move the pointer to the function to the end of the API struct
Created attachment 172257 [details] Sample I did not, but doesn't matter, should have tried an easier example anyway. With the attached example I get: Traceback (most recent call last):
+ Trace 224135
win.add(view)
Seems I can't subclass any widget anymore, which is not a good thing at all.
To clarify, this doesn't work with or without the patch.
Ah, ok, try the patch in bug #631631. That should fix the inheritance issue.
Unfortunately not, the error still persists.
I don't know what is going on with your instance of pygobject. Works fine on my machine with or without the patches on my local branch. Can you run a make check and post the output?
I cleaned my build tree, now with the two patches applied everything works like expected.
With both patches applied, it's no longer throwing the original error, and appears to work as well as with the workaround. It's emitting these warnings: (totem:6851): Gtk-WARNING **: gtktreestore.c:765: Unable to convert from PyObject to GObject ** (totem:6851): WARNING **: Out argument 2 in get_path_at_pos returns a struct with a transfer mode of "full". Transfer mode should be set to "none" for struct type returns as there is no way to free them safely. Ignoring transfer mode to prevent a potential invalid free. This may cause a leak in your application. The second warning is emitted even when using the workaround, so it's probably what's causing the code to not work properly (with or without the workaround).
Philip, The second warning simply doesn't free the struct. We can't free it if it is not boxed (how do we know how it was allocated?) It shouldn't effect your application but really paths should be boxed. What is at issue is gtk_tree_view_get_path_at_pos is a completely broken API as far as introspection is concerned (well the whole tree API is since it trades off consistent API for and simplicity for flexibility and optimisation points). What is at issue is the method signature has a weird mix of caller allocated pointers and callee allocated out parameters. It is just not wrapable and a new API needs to be added which simply returns the path, column and cell coordinates in a sane way. Perhaps something that packs them all in a boxed structure.
Also, can you provide a backtrace for us to look at?
Hmm, actually when looking at the first warning, this issue isn't happening in gtk_tree_view_get_path_at_pos. It is happening in gtk_tree_store_real_set_value. Can you break at gtktreestore.c:765 and copy the backtrace here? Also if you can distil it down to a testcase that would be great.
(totem:14525): Gtk-WARNING **: gtktreestore.c:765: Unable to convert from PyObject to GObject Breakpoint 1, gtk_tree_store_real_set_value (tree_store=0xe171f0, iter=0x89e620, column=0, value=0x89e060, sort=1) at gtktreestore.c:766 766 return retval; Missing separate debuginfos, use: debuginfo-install alsa-plugins-pulseaudio-1.0.22-1.fc13.x86_64 libffi-3.0.9-1.fc13.x86_64 libudev-153-4.fc13.x86_64 libuuid-2.17.2-9.fc13.x86_64 orc-0.4.10-1.fc13.x86_64 (gdb) t a a bt
+ Trace 224294
Thread 1 (Thread 0x7ffff7fb5920 (LWP 14525))
Investigating a little more, the patch is working properly; the plugin was just defining the column in question as a GObject column in the UI file. Changing it to a PyObject fixed things. The other problems in the plugin are separate problems. When can we have a release with this patch applied? :-)
oh, yay, I was thinking the problem was a lot deeper and would need a lot of work to fix but since you found the issue, I'll do a release this week.
Review of attachment 172200 [details] [review]: Looks good to me, some comments: * may exist a better name than pyg_type_from_object_full, what will happen if we need to add another parameter? Also, there's no indication of what that TRUE/FALSE means to the casual reader. * there's spacing errors in test_overrides.py.
Ping? Has this been committed yet? :-)
Yep, it is in the 2.27.0 release :) Thought I closed this.