summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2013-07-29 01:21:19 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2013-07-29 01:42:30 -0700
commitec3de7608ec970f6f272c9d7937344f02c6e9c3d (patch)
treeab113de3d8c34d7bd47da6ebc4f83a9d9913e23f
parentb5dcb1800839f747a052e487643c234668384677 (diff)
downloadpygobject-ec3de7608ec970f6f272c9d7937344f02c6e9c3d.tar.gz
Ensure exceptions set in closure out argument marshaling are printed
Call PyErr_Print when an exception occurs after marshaling closure out arguments. These exceptions were being ignored and cleared out only to show up in debug builds of Python. https://bugzilla.gnome.org/show_bug.cgi?id=705064
-rw-r--r--gi/pygi-closure.c8
-rw-r--r--tests/test_generictreemodel.py17
2 files changed, 19 insertions, 6 deletions
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 601db94b..7582069b 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -33,6 +33,9 @@ _pygi_closure_assign_pyobj_to_retval (gpointer retval, PyObject *object,
GITransfer transfer)
{
GIArgument arg = _pygi_argument_from_object (object, type_info, transfer);
+ if (PyErr_Occurred ())
+ return;
+
GITypeTag type_tag = g_type_info_get_tag (type_info);
if (retval == NULL)
@@ -558,6 +561,11 @@ _pygi_closure_handle (ffi_cif *cif,
}
_pygi_closure_set_out_arguments (closure->info, retval, out_args, result);
+ if (PyErr_Occurred ()) {
+ _pygi_closure_clear_retval (closure->info, result);
+ PyErr_Print();
+ }
+
Py_DECREF (retval);
end:
diff --git a/tests/test_generictreemodel.py b/tests/test_generictreemodel.py
index ff0f5237..9fa89fff 100644
--- a/tests/test_generictreemodel.py
+++ b/tests/test_generictreemodel.py
@@ -314,12 +314,12 @@ class ExceptHook(object):
are never bubbled through from python to C back to python.
This works because exception hooks are called in PyErr_Print.
"""
- def __init__(self, exc_type):
- self._exc_type = exc_type
+ def __init__(self, *expected_exc_types):
+ self._expected_exc_types = expected_exc_types
self._exceptions = []
def _excepthook(self, exc_type, value, traceback):
- self._exceptions.append(exc_type)
+ self._exceptions.append((exc_type, value))
def __enter__(self):
self._oldhook = sys.excepthook
@@ -328,8 +328,13 @@ class ExceptHook(object):
def __exit__(self, exc_type, exc_val, exc_tb):
sys.excepthook = self._oldhook
- assert len(self._exceptions) == 1, 'Expecting exactly one exception of type %s' % self._exc_type
- assert issubclass(self._exceptions[0], self._exc_type), 'Expecting exactly one exception of type %s' % self._exc_type
+ error_message = 'Expecting the following exceptions: %s, got: %s' % \
+ (str(self._expected_exc_types), '\n'.join([str(item) for item in self._exceptions]))
+
+ assert len(self._expected_exc_types) == len(self._exceptions), error_message
+
+ for expected, got in zip(self._expected_exc_types, [exc[0] for exc in self._exceptions]):
+ assert issubclass(got, expected), error_message
class TestReturnsAfterError(unittest.TestCase):
@@ -347,7 +352,7 @@ class TestReturnsAfterError(unittest.TestCase):
self.assertEqual(count, 0)
def test_get_column_type(self):
- with ExceptHook(NotImplementedError):
+ with ExceptHook(NotImplementedError, TypeError):
col_type = self.model.get_column_type(0)
self.assertEqual(col_type, GObject.TYPE_INVALID)