[pygobject] Fix GObject signal methods to work with new annotations
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Fix GObject signal methods to work with new annotations
- Date: Mon, 2 Sep 2013 12:27:51 +0000 (UTC)
commit 9df8eb79929025f12d51bc7f79b1d160156c2755
Author: Simon Feltman <sfeltman src gnome org>
Date: Mon Sep 2 04:19:35 2013 -0700
Fix GObject signal methods to work with new annotations
Add conditional support for signal methods annotated as gpointer
or GObject.Object. This is needed to work with newer versions of
glib which changed annotations to GObject.Object (bug #685387).
https://bugzilla.gnome.org/show_bug.cgi?id=707280
gi/overrides/GObject.py | 106 +++++++++++++++++++++++++++++------------------
1 files changed, 66 insertions(+), 40 deletions(-)
---
diff --git a/gi/overrides/GObject.py b/gi/overrides/GObject.py
index 044c36e..b3aad47 100644
--- a/gi/overrides/GObject.py
+++ b/gi/overrides/GObject.py
@@ -425,20 +425,21 @@ def signal_query(id_or_name, type_=None):
__all__.append('signal_query')
+# Check needed for glib versions which annotate signal related methods
+# with a void pointer instead of GObject.Object.
+# See: https://bugzilla.gnome.org/show_bug.cgi?id=685387
+_is_first_signal_arg_void = GObjectModule.signal_stop_emission.get_arguments()[0].get_pytype_hint() == 'void'
+
+
def _get_instance_for_signal(obj):
- if isinstance(obj, GObjectModule.Object):
+ if not _is_first_signal_arg_void:
+ return obj
+ elif isinstance(obj, GObjectModule.Object):
return obj.__gpointer__
else:
raise TypeError('Unsupported object "%s" for signal function' % obj)
-def _wrap_signal_func(func):
- @functools.wraps(func)
- def wrapper(obj, *args, **kwargs):
- return func(_get_instance_for_signal(obj), *args, **kwargs)
- return wrapper
-
-
class _HandlerBlockManager(object):
def __init__(self, obj, handler_id):
self.obj = obj
@@ -466,32 +467,47 @@ def signal_handler_block(obj, handler_id):
__all__.append('signal_handler_block')
-# The following functions wrap GI functions but coerce the first arg into
-# something compatible with gpointer
-
-signal_handler_unblock = _wrap_signal_func(GObjectModule.signal_handler_unblock)
-signal_handler_disconnect = _wrap_signal_func(GObjectModule.signal_handler_disconnect)
-signal_handler_is_connected = _wrap_signal_func(GObjectModule.signal_handler_is_connected)
-signal_stop_emission = _wrap_signal_func(GObjectModule.signal_stop_emission)
-signal_stop_emission_by_name = _wrap_signal_func(GObjectModule.signal_stop_emission_by_name)
-signal_has_handler_pending = _wrap_signal_func(GObjectModule.signal_has_handler_pending)
-signal_get_invocation_hint = _wrap_signal_func(GObjectModule.signal_get_invocation_hint)
-signal_connect_closure = _wrap_signal_func(GObjectModule.signal_connect_closure)
-signal_connect_closure_by_id = _wrap_signal_func(GObjectModule.signal_connect_closure_by_id)
-signal_handler_find = _wrap_signal_func(GObjectModule.signal_handler_find)
-signal_handlers_destroy = _wrap_signal_func(GObjectModule.signal_handlers_destroy)
-signal_handlers_block_matched = _wrap_signal_func(GObjectModule.signal_handlers_block_matched)
-signal_handlers_unblock_matched = _wrap_signal_func(GObjectModule.signal_handlers_unblock_matched)
-signal_handlers_disconnect_matched = _wrap_signal_func(GObjectModule.signal_handlers_disconnect_matched)
-
-__all__ += ['signal_handler_unblock',
- 'signal_handler_disconnect', 'signal_handler_is_connected',
- 'signal_stop_emission', 'signal_stop_emission_by_name',
- 'signal_has_handler_pending', 'signal_get_invocation_hint',
- 'signal_connect_closure', 'signal_connect_closure_by_id',
- 'signal_handler_find', 'signal_handlers_destroy',
- 'signal_handlers_block_matched', 'signal_handlers_unblock_matched',
- 'signal_handlers_disconnect_matched']
+if _is_first_signal_arg_void:
+ # The following functions wrap GI functions but coerce the first arg into
+ # something compatible with gpointer
+
+ def _wrap_signal_func(func):
+ @functools.wraps(func)
+ def wrapper(obj, *args, **kwargs):
+ return func(_get_instance_for_signal(obj), *args, **kwargs)
+ return wrapper
+
+ signal_handler_unblock = _wrap_signal_func(GObjectModule.signal_handler_unblock)
+ signal_handler_disconnect = _wrap_signal_func(GObjectModule.signal_handler_disconnect)
+ signal_handler_is_connected = _wrap_signal_func(GObjectModule.signal_handler_is_connected)
+ signal_stop_emission = _wrap_signal_func(GObjectModule.signal_stop_emission)
+ signal_stop_emission_by_name = _wrap_signal_func(GObjectModule.signal_stop_emission_by_name)
+ signal_has_handler_pending = _wrap_signal_func(GObjectModule.signal_has_handler_pending)
+ signal_get_invocation_hint = _wrap_signal_func(GObjectModule.signal_get_invocation_hint)
+ signal_connect_closure = _wrap_signal_func(GObjectModule.signal_connect_closure)
+ signal_connect_closure_by_id = _wrap_signal_func(GObjectModule.signal_connect_closure_by_id)
+ signal_handler_find = _wrap_signal_func(GObjectModule.signal_handler_find)
+ signal_handlers_destroy = _wrap_signal_func(GObjectModule.signal_handlers_destroy)
+ signal_handlers_block_matched = _wrap_signal_func(GObjectModule.signal_handlers_block_matched)
+ signal_handlers_unblock_matched = _wrap_signal_func(GObjectModule.signal_handlers_unblock_matched)
+ signal_handlers_disconnect_matched = _wrap_signal_func(GObjectModule.signal_handlers_disconnect_matched)
+
+ __all__ += ['signal_handler_unblock',
+ 'signal_handler_disconnect', 'signal_handler_is_connected',
+ 'signal_stop_emission', 'signal_stop_emission_by_name',
+ 'signal_has_handler_pending', 'signal_get_invocation_hint',
+ 'signal_connect_closure', 'signal_connect_closure_by_id',
+ 'signal_handler_find', 'signal_handlers_destroy',
+ 'signal_handlers_block_matched', 'signal_handlers_unblock_matched',
+ 'signal_handlers_disconnect_matched']
+else:
+ # First signal arg is GObject.Object but we need these as globals for
+ # our GObject.Object class override below
+ signal_handler_disconnect = GObjectModule.signal_handler_disconnect
+ signal_handler_unblock = GObjectModule.signal_handler_unblock
+ signal_handler_disconnect = GObjectModule.signal_handler_disconnect
+ signal_handler_is_connected = GObjectModule.signal_handler_is_connected
+ signal_stop_emission_by_name = GObjectModule.signal_stop_emission_by_name
def signal_parse_name(detailed_signal, itype, force_detail_quark):
@@ -556,6 +572,16 @@ class _FreezeNotifyManager(object):
self.obj.thaw_notify()
+def _signalmethod(func):
+ # Function wrapper for signal functions used as instance methods.
+ # This is needed when the signal functions come directly from GI.
+ # (they are not already wrapped)
+ @functools.wraps(func)
+ def meth(*args, **kwargs):
+ return func(*args, **kwargs)
+ return meth
+
+
class Object(GObjectModule.Object):
def _unsupported_method(self, *args, **kargs):
raise RuntimeError('This method is currently unsupported.')
@@ -635,12 +661,12 @@ class Object(GObjectModule.Object):
# Aliases
#
- disconnect = signal_handler_disconnect
- handler_block = signal_handler_block
- handler_unblock = signal_handler_unblock
- handler_disconnect = signal_handler_disconnect
- handler_is_connected = signal_handler_is_connected
- stop_emission_by_name = signal_stop_emission_by_name
+ disconnect = _signalmethod(signal_handler_disconnect)
+ handler_block = _signalmethod(signal_handler_block)
+ handler_unblock = _signalmethod(signal_handler_unblock)
+ handler_disconnect = _signalmethod(signal_handler_disconnect)
+ handler_is_connected = _signalmethod(signal_handler_is_connected)
+ stop_emission_by_name = _signalmethod(signal_stop_emission_by_name)
#
# Deprecated Methods
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]