summaryrefslogtreecommitdiff
path: root/gi
diff options
context:
space:
mode:
Diffstat (limited to 'gi')
-rw-r--r--gi/_gobject/propertyhelper.py12
-rw-r--r--gi/_gobject/pygtype.c4
-rw-r--r--gi/overrides/GObject.py106
-rw-r--r--gi/pygi-closure.c3
-rw-r--r--gi/pygi-marshal-from-py.c8
-rw-r--r--gi/pygi-signal-closure.c2
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");