[pygobject/pygobject-3-8] Clear return value of closures to zero when an exception occures
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/pygobject-3-8] Clear return value of closures to zero when an exception occures
- Date: Wed, 3 Jul 2013 08:57:16 +0000 (UTC)
commit 1aa76b846d311544311a48fc10261d9ac24229f5
Author: Simon Feltman <sfeltman src gnome org>
Date: Tue Jul 2 23:02:17 2013 -0700
Clear return value of closures to zero when an exception occures
For return types other than void, set the ffi closure return argument
to 0 when a Python exception occures. This a good default in general
but also has the side affect of fixing failing idle callbacks
by causing them to be removed from main loops (after their stack
is printed).
https://bugzilla.gnome.org/show_bug.cgi?id=702552
gi/pygi-closure.c | 14 ++++++++++++++
tests/test_gi.py | 8 ++++++++
2 files changed, 22 insertions(+), 0 deletions(-)
---
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index f30fa52..99e15a1 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -108,6 +108,19 @@ _pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object,
}
static void
+_pygi_closure_clear_retval (GICallableInfo *callable_info, gpointer retval)
+{
+ GITypeInfo return_type_info;
+ GITypeTag return_type_tag;
+
+ g_callable_info_load_return_type (callable_info, &return_type_info);
+ return_type_tag = g_type_info_get_tag (&return_type_info);
+ if (return_type_tag != GI_TYPE_TAG_VOID) {
+ *((ffi_arg *) retval) = 0;
+ }
+}
+
+static void
_pygi_closure_assign_pyobj_to_out_argument (gpointer out_arg, PyObject *object,
GITypeInfo *type_info,
GITransfer transfer)
@@ -546,6 +559,7 @@ _pygi_closure_handle (ffi_cif *cif,
Py_DECREF (py_args);
if (retval == NULL) {
+ _pygi_closure_clear_retval (closure->info, result);
PyErr_Print();
goto end;
}
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 13e87f4..2efb478 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -2087,6 +2087,10 @@ class TestPythonGObject(unittest.TestCase):
self.variants = variants
self.n_variants = n_variants
+ class ErrorObject(GIMarshallingTests.Object):
+ def do_vfunc_return_value_only(self):
+ raise ValueError('Return value should be 0')
+
def test_object(self):
self.assertTrue(issubclass(self.Object, GIMarshallingTests.Object))
@@ -2246,6 +2250,10 @@ class TestPythonGObject(unittest.TestCase):
_object.call_vfunc_with_callback()
self.assertTrue(_object.worked)
+ def test_exception_in_vfunc_return_value(self):
+ obj = self.ErrorObject()
+ self.assertEqual(obj.vfunc_return_value_only(), 0)
+
class TestMultiOutputArgs(unittest.TestCase):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]