diff options
Diffstat (limited to 'gi')
-rw-r--r-- | gi/_gobject/propertyhelper.py | 12 | ||||
-rw-r--r-- | gi/_gobject/pygtype.c | 4 | ||||
-rw-r--r-- | gi/overrides/GObject.py | 106 | ||||
-rw-r--r-- | gi/pygi-closure.c | 3 | ||||
-rw-r--r-- | gi/pygi-marshal-from-py.c | 8 | ||||
-rw-r--r-- | gi/pygi-signal-closure.c | 2 |
6 files changed, 84 insertions, 51 deletions
diff --git a/gi/_gobject/propertyhelper.py b/gi/_gobject/propertyhelper.py index 162d30a..c9400df 100644 --- a/gi/_gobject/propertyhelper.py +++ b/gi/_gobject/propertyhelper.py @@ -185,16 +185,16 @@ class Property(object): if minimum is not None: if minimum < self._get_minimum(): raise TypeError( - "Minimum for type %s cannot be lower than %d" % ( - self.type, self._get_minimum())) + "Minimum for type %s cannot be lower than %d" % + (self.type, self._get_minimum())) else: minimum = self._get_minimum() self.minimum = minimum if maximum is not None: if maximum > self._get_maximum(): raise TypeError( - "Maximum for type %s cannot be higher than %d" % ( - self.type, self._get_maximum())) + "Maximum for type %s cannot be higher than %d" % + (self.type, self._get_maximum())) else: maximum = self._get_maximum() self.maximum = maximum @@ -393,8 +393,8 @@ def install_properties(cls): raise TypeError( "GObject subclass %r defines do_get/set_property" " and it also uses a property with a custom setter" - " or getter. This is not allowed" % ( - cls.__name__,)) + " or getter. This is not allowed" % + (cls.__name__,)) def obj_get_property(self, pspec): name = pspec.name.replace('-', '_') diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c index 0b920f6..9dc1153 100644 --- a/gi/_gobject/pygtype.c +++ b/gi/_gobject/pygtype.c @@ -1362,7 +1362,7 @@ pyg_closure_marshal(GClosure *closure, goto out; } - if (return_value && pyg_value_from_pyobject(return_value, ret) != 0) { + if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { /* If we already have an exception set, use that, otherwise set a * generic one */ if (!PyErr_Occurred()) @@ -1543,7 +1543,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, } Py_DECREF(method); Py_DECREF(params); - if (return_value) + if (G_IS_VALUE(return_value)) pyg_value_from_pyobject(return_value, ret); Py_DECREF(ret); pyglib_gil_state_release(state); 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 diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c index 7582069..2f5548a 100644 --- a/gi/pygi-closure.c +++ b/gi/pygi-closure.c @@ -33,10 +33,11 @@ _pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object, GITransfer transfer) { GIArgument arg = _pygi_argument_from_object (object, type_info, transfer); + GITypeTag type_tag; if (PyErr_Occurred ()) return; - GITypeTag type_tag = g_type_info_get_tag (type_info); + type_tag = g_type_info_get_tag (type_info); if (retval == NULL) return; diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c index a48479b..82d94a0 100644 --- a/gi/pygi-marshal-from-py.c +++ b/gi/pygi-marshal-from-py.c @@ -1827,7 +1827,13 @@ _pygi_marshal_from_py_interface_struct (PyObject *py_arg, } if (g_type_is_a (g_type, G_TYPE_BOXED)) { - if (pyg_boxed_check (py_arg, g_type)) { + /* Use pyg_type_from_object to pull the stashed __gtype__ attribute + * off of the input argument instead of checking PyGBoxed.gtype + * with pyg_boxed_check. This is needed to work around type discrepancies + * in cases with aliased (typedef) types. e.g. GtkAllocation, GdkRectangle. + * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140 + */ + if (g_type_is_a (pyg_type_from_object (py_arg), g_type)) { arg->v_pointer = pyg_boxed_get (py_arg, void); if (transfer == GI_TRANSFER_EVERYTHING) { arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer); diff --git a/gi/pygi-signal-closure.c b/gi/pygi-signal-closure.c index 20c6b56..bcd1320 100644 --- a/gi/pygi-signal-closure.c +++ b/gi/pygi-signal-closure.c @@ -155,7 +155,7 @@ pygi_signal_closure_marshal(GClosure *closure, goto out; } - if (return_value && pyg_value_from_pyobject(return_value, ret) != 0) { + if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { PyErr_SetString(PyExc_TypeError, "can't convert return value to desired type"); |