GNOME Bugzilla – Bug 688783
Marshalling of out parameters not working properly
Last modified: 2012-11-21 14:15:43 UTC
It looks like marshalling of out parameters doesn't work as expected in all cases, see the following gir snippet: <virtual-method name="get_field_schema" invoker="get_field_schema"> <doc xml:whitespace="preserve">Get the #GVariant signature of field previously registered with dee_model_register_vardict_schema().</doc> <return-value transfer-ownership="none"> <doc xml:whitespace="preserve">the #GVariant signature for the field, or %NULL if given field wasn't registered with dee_model_register_vardict_schema().</doc> <type name="utf8" c:type="const gchar*"/> </return-value> <parameters> <parameter name="field_name" transfer-ownership="none"> <doc xml:whitespace="preserve">name of vardict field to get schema of</doc> <type name="utf8" c:type="const gchar*"/> </parameter> <parameter name="out_column" direction="out" caller-allocates="0" transfer-ownership="none"> <doc xml:whitespace="preserve">column index of the associated vardict</doc> <type name="guint" c:type="guint*"/> </parameter> </parameters> </virtual-method> When invoking the method I get:
+ Trace 231207
col_schema, col_index = self.get_field_schema(col_name)
return info.invoke(*args, **kwargs)
For sake of completeness, here are the method annotations: /** * dee_model_get_field_schema: * @self: a #DeeModel * @field_name: name of vardict field to get schema of * @out_column: (out): column index of the associated vardict * * Get the #GVariant signature of field previously registered with * dee_model_register_vardict_schema(). * * Return value: the #GVariant signature for the field, or %NULL if given field * wasn't registered with dee_model_register_vardict_schema(). */ const gchar* dee_model_get_field_schema (DeeModel *self, const gchar *field_name, guint *out_column);
Hi Michal, It looks like we have tests for similar things (but not exactly). See: http://git.gnome.org/browse/pygobject/tree/tests/test_gi.py http://git.gnome.org/browse/gobject-introspection/tree/tests/gimarshallingtests.c and search for: vfunc_multiple_out_parameters The main difference I see between your example and the tests is the tests don't specify an annotation for the self parameter. While the virtual-method definition in the gir does not show a self parameter, I wonder if the method definition does?
Created attachment 229568 [details] [review] [gi] Test virtual methods with in and out arguments I reproduced this exact API in GIMarshallingTests. We didn't previously cover the case of a virtual method having a caller allocated (out) argument and an additional (in) argument.
Created attachment 229569 [details] [review] Test virtual methods with in and out arguments This adds PyGObject tests for both cases, i. e. caller and callee allocated. Both already work fine on current master.
My current /usr/share/gir-1.0/Dee-1.0.gir (dee version 1.0.14) does not have this API and neither has upstream ("bzr branch lp:dee"). Is that a local modification/addition you didn't commit yet? How can I reproduce this?
I checked out lp:~mhr3/dee/easy-hints. There the annotatios are wrong: <virtual-method name="get_field_schema" invoker="get_field_schema"> [...] <parameter name="out_column" direction="out" caller-allocates="0" transfer-ownership="full"> <doc xml:whitespace="preserve">column index of the associated vardict</doc> <type name="guint" c:type="guint*"/> </parameter> You cannot have a callee-allocated uint passed through a guint*, that needs to be a guint** then so that get_field_schema() can return a newly allocated pointer to the caller. Or use caller allocation (which probably makes more sense for a single int). Anyway, this reproduces with checking out the branch, ./autogen.sh/make, and then cd src PYTHONPATH=. GI_TYPELIB_PATH=. LD_LIBRARY_PATH=.libs/ python3 /tmp/test.py I'll investigate this now.
Sorry, forgot the actual test.py: from gi.repository import Dee m = Dee.SequenceModel() m.set_schema_full(("s", "u", "a{sv}")) m.set_column_names_full(("foo", "bar", "hints")) m.register_vardict_schema(2, {'id': 'i'}) print(m.get_field_schema("id"))
I extended the g-i and pygobject tests to cover the exact same signature that you have, and everything works. Now I got it: the <virtual-method name="get_field_schema" invoker="get_field_schema"> I was looking at before does have the (out) direction, but that's not the one that is being called! This belongs to the interface, but it calls the real method instead: <method name="get_field_schema" c:identifier="dee_model_get_field_schema"> [...] <parameter name="column" transfer-ownership="none"> <type name="guint" c:type="guint*"/> </parameter> which is not annotated as (out). If I fix the .gir to include the out direction, it works: PYTHONPATH=. GI_TYPELIB_PATH=. LD_LIBRARY_PATH=.libs/ python3 /tmp/test.py ('i', 2) I committed updated variants of the g-i tests and PyGObject tests anyway, now that I have them.