diff options
-rw-r--r-- | gobject/pygobject.c | 7 | ||||
-rw-r--r-- | gobject/pygtype.c | 23 |
2 files changed, 25 insertions, 5 deletions
diff --git a/gobject/pygobject.c b/gobject/pygobject.c index 07a33a77..efa51b26 100644 --- a/gobject/pygobject.c +++ b/gobject/pygobject.c @@ -991,7 +991,10 @@ pygobject_chain_from_overridden(PyGObject *self, PyObject *args) for (i = 0; i < query.n_params; i++) { PyObject *item = PyTuple_GetItem(args, i); - if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { + if (pyg_boxed_check(item, (query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE))) { + g_value_set_static_boxed(¶ms[i+1], pyg_boxed_get(item, void)); + } + else if (pyg_value_from_pyobject(¶ms[i+1], item) < 0) { gchar buf[128]; g_snprintf(buf, sizeof(buf), @@ -1011,7 +1014,7 @@ pygobject_chain_from_overridden(PyGObject *self, PyObject *args) for (i = 0; i < query.n_params + 1; i++) g_value_unset(¶ms[i]); g_free(params); - if ((query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE) != G_TYPE_NONE) { + if (query.return_type != G_TYPE_NONE) { py_ret = pyg_value_as_pyobject(&ret, TRUE); g_value_unset(&ret); } else { diff --git a/gobject/pygtype.c b/gobject/pygtype.c index 56eca377..85bef4a1 100644 --- a/gobject/pygtype.c +++ b/gobject/pygtype.c @@ -850,7 +850,7 @@ pyg_signal_class_closure_marshal(GClosure *closure, gchar *method_name, *tmp; PyObject *method; PyObject *params, *ret; - guint i; + guint i, len; g_return_if_fail(invocation_hint != NULL); @@ -883,10 +883,11 @@ pyg_signal_class_closure_marshal(GClosure *closure, } Py_DECREF(object_wrapper); - /* construct Python tuple for the parameter values */ + /* construct Python tuple for the parameter values; don't copy boxed values + initially because we'll check after the call to see if a copy is needed. */ params = PyTuple_New(n_param_values - 1); for (i = 1; i < n_param_values; i++) { - PyObject *item = pyg_value_as_pyobject(¶m_values[i], TRUE); + PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); /* error condition */ if (!item) { @@ -898,6 +899,22 @@ pyg_signal_class_closure_marshal(GClosure *closure, } ret = PyObject_CallObject(method, params); + + /* Copy boxed values if others ref them, this needs to be done regardless of + exception status. */ + len = PyTuple_Size(params); + for (i = 0; i < len; i++) { + PyObject *item = PyTuple_GetItem(params, i); + if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type) + && item->ob_refcnt != 1) { + PyGBoxed* boxed_item = (PyGBoxed*)item; + if (!boxed_item->free_on_dealloc) { + boxed_item->boxed = g_boxed_copy(boxed_item->gtype, boxed_item->boxed); + boxed_item->free_on_dealloc = TRUE; + } + } + } + if (ret == NULL) { PyErr_Print(); Py_DECREF(method); |