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 680016 - Problems returning values
Problems returning values
Status: RESOLVED OBSOLETE
Product: pygobject
Classification: Bindings
Component: gobject
3.2.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-07-16 14:20 UTC by Hagen Fritsch
Modified: 2012-10-16 07:30 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Hagen Fritsch 2012-07-16 14:20:07 UTC
While trying to port code based on pygtk's GenericTreeModel, I stumbled into a long list of problem.
A major in is that for example the function TreeModel.do_get_iter is not wrapped correctly (see also https://bugs.launchpad.net/bugs/1024492)

According to the .gir-File the function should return (True, gtk_tree_iter) which does not work as expected.
I suspect, that this is due to the argument being caller-allocated.
What happens is, that the value returned (i.e. 1234 of (True, 1234)) is written to the caller-allocated objects first field, in this case the stamp attribute of the GtkTreeIter. The other attributes seem left at 0.

When changing the direction of the iter argument to "inout", the function should become do_get_iter(self, iter, path). However, iter is always None in this case and thus cannot be modified.

Setting the direction to "in" works and one can edit the properties of the caller-allocated iter.

I think a similar problem occurs for the TreeModel.do_get_value function, which should return a GValue. However, it is again caller-allocated, so returning a string or a corresponding new GObject.Value() does not work.
When again changing the direction to "in", the method is not called as the GValue is not yet initialized which raises a "TypeError: unknown type (null)".

These problems effectively hinder development of custom TreeModels for python.
Comment 1 Hagen Fritsch 2012-07-17 13:52:57 UTC
Here is a simple test-case for the problem, throwing a segmentation fault:

    import gi
    from gi.repository import Gtk as gtk, GObject

    class TreeModel(GObject.GObject, gtk.TreeModel):
        def do_get_value(self, iter, column):
            x = GObject.Value()
            x.init(GObject.TYPE_STRING)
            x.set_string("foo")
            return x

    t = TreeModel()
    print t.get_value(gtk.TreeIter(), 1)
Comment 2 Hagen Fritsch 2012-07-17 15:39:32 UTC
So a little more results. Consider the following:

        def do_get_value(self, iter, column):
            return "bar"

which raises the error TypeError: unknown type (null) in pygtype.c:1153

Turns out the return value is correctly marshalled into a GValue object, which is then stored as a GIArgument.
Now when the object is to be marshalled to a python object in _invoke_marshal_out_args, somehow the GIArgument is assumed to be a GValue already and thus the error is raised.

I think (but I’m not so sure), that the error has somehow to do with the double indirection:
out_args in _pygi_closure_set_out_arguments is a GIArgument list.
Now out_args[0].v_pointer points again to GIArgument pointing to the GValue.
Don't know though how and where exactly the cause for the bug is though…
Comment 3 Hagen Fritsch 2012-07-17 17:35:56 UTC
So coming to a conclusion: the direction=out arguments for these methods with caller-allocates=1 should be direction=in, so that they are passed to the function and the function can manipulate them (i.e. set the GValue).
However, the problem with the get_value method persists as it is tried to marshall the argument to the python type (causing the "TypeError: unknown type (null)" error). Even if the value were initialized already, the python-value of it would be passed instead of the GObject.Value object and then the callee wouldn't be able to manipulate the object.
To avoid having other side-effects the marshalling could only be disabled if caller-allocates is set.

Other than that there could be a special handling of these cases, copying the whole object that was returned from the function to the corresponding original pointer argument.
Comment 4 Simon Feltman 2012-07-30 07:09:21 UTC
I've been running into similar issues trying to implement a TreeModel as well. However, your current example seems to work fine on the latest pygobject source repository.

Also note that inout and out parameters should be returned from the methods in question in a tuple along with the regular return value. So do_get_iter should return (True, iter).

This bug (and patch) may also be of interest: https://bugzilla.gnome.org/show_bug.cgi?id=680812
Comment 5 Simon Feltman 2012-10-16 07:30:39 UTC
The example given no longer produces errors. Please re-open with new steps and the pygobject version you are using if you are still seeing this problem.