After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 688783 - Marshalling of out parameters not working properly
Marshalling of out parameters not working properly
Status: RESOLVED NOTABUG
Product: pygobject
Classification: Bindings
Component: general
3.4.x
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2012-11-21 08:37 UTC by Michal Hruby
Modified: 2012-11-21 14:15 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[gi] Test virtual methods with in and out arguments (3.17 KB, patch)
2012-11-21 12:00 UTC, Martin Pitt
none Details | Review
Test virtual methods with in and out arguments (1.38 KB, patch)
2012-11-21 12:01 UTC, Martin Pitt
none Details | Review

Description Michal Hruby 2012-11-21 08:37:21 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:

  • File "/usr/lib/python2.7/dist-packages/gi/overrides/Dee.py", line 88 in _build_row
    col_schema, col_index = self.get_field_schema(col_name)
  • File "/usr/lib/python2.7/dist-packages/gi/types.py", line 47 in function
    return info.invoke(*args, **kwargs)
TypeError: get_field_schema() takes exactly 3 arguments (2 given)

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);
Comment 1 Simon Feltman 2012-11-21 09:26:33 UTC
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?
Comment 2 Martin Pitt 2012-11-21 12:00:01 UTC
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.
Comment 3 Martin Pitt 2012-11-21 12:01:02 UTC
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.
Comment 4 Martin Pitt 2012-11-21 12:03:26 UTC
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?
Comment 5 Martin Pitt 2012-11-21 12:30:17 UTC
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.
Comment 6 Martin Pitt 2012-11-21 12:57:53 UTC
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"))
Comment 7 Martin Pitt 2012-11-21 14:15:43 UTC
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.