diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2013-07-29 01:21:19 -0700 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2013-07-29 01:42:30 -0700 |
commit | ec3de7608ec970f6f272c9d7937344f02c6e9c3d (patch) | |
tree | ab113de3d8c34d7bd47da6ebc4f83a9d9913e23f | |
parent | b5dcb1800839f747a052e487643c234668384677 (diff) | |
download | pygobject-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.c | 8 | ||||
-rw-r--r-- | tests/test_generictreemodel.py | 17 |
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) |