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 633999 - Provide bindable version of signal handler query functions
Provide bindable version of signal handler query functions
Status: RESOLVED DUPLICATE of bug 685387
Product: gobject-introspection
Classification: Platform
Component: general
2.27.x
Other Linux
: Normal normal
: ---
Assigned To: gobject-introspection Maintainer(s)
gobject-introspection Maintainer(s)
Depends on:
Blocks: 633927 692918
 
 
Reported: 2010-11-04 15:19 UTC by Michael Terry
Modified: 2015-02-07 16:52 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add GObject.Object type annotation to all g_signal_* functions. (7.84 KB, patch)
2012-11-12 05:40 UTC, Simon Feltman
none Details | Review

Description Michael Terry 2010-11-04 15:19:07 UTC
There are many g_signal_handler query functions (find, block_matched, disconnect_matched, etc) that were never bound in pygobject (and now crash when used with PyGI -- bug 633927) because they use many difficult to bind constructs like generic gpointers, GQuarks, and closures.

Is it possible to either annotate those correctly or provide a different API that is binding-friendly?
Comment 1 Colin Walters 2010-12-06 20:39:31 UTC
Generally I've been saying that anything in GLib/GObject may require manual overrides.  In this case, it's hard to say...what exactly are you trying to do?

Probably the right thing is to add some sort of lowlevel API to pygobject for this.
Comment 2 Michael Terry 2010-12-06 20:54:10 UTC
I was writing a python function to automatically connect signals to methods on a class with a well-defined handler name pattern.  But I wanted to avoid doing so if glade had already setup the same connection.  So I wanted to query to see if a given signal had been connected to a given method yet, before I made that same connection.
Comment 3 Colin Walters 2010-12-06 21:18:41 UTC
That makes sense (having these real-world use cases is really helpful for evaluating bugs).

The problem with this case is that the binding layer (pygobject) is going to be dynamically creating C closures for the signal handlers, and that's all that GObject knows about.  In other words when you do:

def foo(w, c):
  print "drawing on " + c
foo.connect('draw', foo)

There's a new C function created, and there's no sane way to say e.g.:

foo.has_connected('draw', foo)

without traversing the internal binding layer.

In other words - reassigning to pygobject if you want this, it needs to be there.
Comment 4 Michael Terry 2010-12-06 21:45:37 UTC
Though to be clear, in my specific example, I didn't want to call a fictional has_connected to check for connections made by pygobject but by the C glade library.  For which you would have enough information, right?
Comment 5 Michael Terry 2010-12-06 21:47:44 UTC
Sorry, that's probably non-sensical.  I actually assume there would still need to be python-side connection code (probably by the python glade bindings).
Comment 6 johnp 2010-12-07 00:18:00 UTC
I wouldn't use python-glade with PyGI.  First glade is deprecated in favour of GtkBuilder, second, python-glade pulls in PyGTK, which definitely won't work with PyGI.

In any case this seems like a really hard thing to support from the python side.  It would be a lot of bookkeeping code to be able to translate bidirectionally between the C closure and the python method.  All of that for an edge usecase.  An application should be able to track these things for themselves.

Perhaps I am not fully understanding the example but most of the convenience methods boil down to a gobject.connect_object_* call.  We never magically hook up callbacks to the point that an application couldn't replicate the methods, adding some bookkeeping in between.  Since you can dictate what goes into the apps you can specify developers must use your bookkeeping methods to hook up callbacks.  

If you look at the GtkBuilder override we provide we simply call the Gtk.Builder.connect_signals_full method with a function and an object (or dictionary of callbacks).  For each signal defined in the UI file, the builder calls the function we provided and passes the object as user data.  We then look at the handler name defined in the UI file and see if there is a corresponding method and hook it up using the connect_object_* API.  You could simply copy and paste that and add your bookkeeping code.  The one thing I can see us adding here is a hook that gets called if it can't find the handler which an application could use to add their own logic to hooking up a signal to a handler.  That would avoid bookkeeping.

[1] http://git.gnome.org/browse/pygobject/tree/gi/overrides/Gtk.py#n267
Comment 7 Sebastian Pölsterl 2012-04-21 09:49:36 UTC
Is there an update on this issue whether it can be fixed or not?
Comment 8 Tobias Mueller 2012-09-28 05:56:36 UTC
If I read it right, this is WONTFIX. Please reopen if this is not the case.
Comment 9 Simon Feltman 2012-11-12 05:35:58 UTC
Re-opening as a number of these functions are easily fixed by supplying a type annotation to the instance argument:

/**
 * g_signal_stop_emission:
 * @instance: (type GObject.Object): ...
 ...
*/
Comment 10 Simon Feltman 2012-11-12 05:40:51 UTC
Created attachment 228748 [details] [review]
Add GObject.Object type annotation to all g_signal_* functions.
Comment 11 Simon Feltman 2012-11-12 05:48:28 UTC
It also seems plausible these functions accept instance types besides GObjects. If that is the case than we should change the annotations to (skip) unless someone has a better idea?
Comment 12 Martin Pitt 2012-11-12 06:37:28 UTC
Signals also work on other fundamental objects as far as I know. However, this patch would turn "does not work for anything through GI" into "only works for GObjects through GI", which is certainly a huge improvement, as that covers the vast majority of use cases.
Comment 13 Simon Feltman 2012-12-18 09:58:51 UTC
These annotations will allow easy removal of the following statically implemented methods in pygobject:

pygobject_disconnect
pygobject_handler_is_connected
pygobject_handler_block
pygobject_handler_unblock
pygobject_stop_emission

And with a bit of work we should be able to remove the following:

pygobject_connect
pygobject_connect_after
pygobject_connect_object
pygobject_connect_object_after
pygobject_emit

Together, all of this could be a significant reduction in the amount of code in pygobject.c

I think for now using GObject.Object for the annotations will help a lot. And eventually the goal should be to change the annotations use a special "any gtype" annotation, but that will require a log more changes across the board.
Comment 14 Simon Feltman 2013-01-31 12:22:36 UTC
Closing as this will no longer be needed. We are able to overcome the problem by exposing a pointer to the underlying GObject by wrapping it with a PyCapsule as a private attribute (__gpointer__). pygi marshaling can then extract the raw pointer from the capsule and pass it in. This will also allow us to have thin wrappers which work for other types, not just GObjects.
Comment 15 Simon Feltman 2013-01-31 12:24:05 UTC
Comment on attachment 228748 [details] [review]
Add GObject.Object type annotation to all g_signal_* functions.

Need replaced by other means, see: bug 692918
Comment 16 Simon Feltman 2013-09-02 22:14:25 UTC
Changing to dup for future reference.

*** This bug has been marked as a duplicate of bug 685387 ***
Comment 17 André Klapper 2015-02-07 16:52:59 UTC
[Mass-moving gobject-introspection tickets to its own Bugzilla product - see bug 708029. Mass-filter your bugmail for this message: introspection20150207 ]