GNOME Bugzilla – Bug 666636
Support marshalling list of strings into a GValue
Last modified: 2013-07-26 01:16:49 UTC
I've got one C method which takes a GHashTable<string,GValue>. When I invoke this method from python, ====== strings = ['one', two', three'] data = {} data['plain_string'] = 'hi, this works' data['strings' = strings ====== the 'plain_string' is correctly converted into a GValue holding a UTF-8 string, but the 'strings' parameter holds a PyObject, and not a GStrv as I would expect (or maybe a GValueArray, if the list element are of different types).
I think a found a solution: =========== class GStrv(list): __gtype__ = GObject.type_from_name('GStrv') strings = ['one', two', three'] data = {} data['plain_string'] = 'hi, this works' data['strings'] = GStrv(strings) =========== So, as far as I'm concerned, this bug can be closed. :-) I'll leave it the decision to the python-gobject folks, because maybe they'd like to have this case working without this "hack".
I applied that workaround in the tests for now, so that we can actually run this test case: http://git.gnome.org/browse/pygobject/commit/?id=88d189ec3e3d900a96496a50c1d6e76615b19558 I need the test case for bug 637466, and it's good to have it anyway. Thanks for the workaround!
There is really no good way we can fix this in terms of being able to pass a list of strings directly. Basically we do not have a GI annotation describing the expected marshaling to a GStrv (only the actual code within the C function being called knows what is expected). We could attempt a deeper analysis of the Python data and use a heuristic when converting to a GValue (Python list of strings is always a boxed GStrv). But I think the right way to deal with this is for clients of the API to explicitly create the GValue which the API is expecting: strings = ['first', 'second', 'third'] data['strings'] = GObject.Value(GObject.TYPE_STRV, strings) This creates a properly marshaled and boxed Strv from Python strings which show up on the C end correctly. However, this depends on bug #688081 to be fixed (not the deprecation but the overrides for GValue.set/get_boxed).
Depends on GValue.set/get_boxed override patch in bug #688081, not the deprecations.
Created attachment 250087 [details] [review] tests: Change GHashTable<string,GValue> marshaling test to use GValue Patch for the tests. For the record, I am not against adding GStrv to the GLib overrides (GLib.Strv) as a slightly cleaner workaround. In which case we should add tests for both cases.
Comment on attachment 250087 [details] [review] tests: Change GHashTable<string,GValue> marshaling test to use GValue This looks slightly less hard to discover :-) and is shorter, thanks!
I ended up adding the GObject.Value technique as an additional test rather than replacing the list sub-class (GStrv(list)). I think the sub-class is still useful and keeping the test will help us avoid regressions. The following fix has been pushed: f86701b tests: Change GHashTable<string,GValue> marshaling test to use GValue
Created attachment 250166 [details] [review] tests: Change GHashTable<string,GValue> marshaling test to use GValue Add test to explicitly use a boxed GStrv GValue in addition to a Python list sub-class.