From 02f815401f09b07bccfce01d3a5abb19b3a34095 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 17 May 2005 17:47:10 +0000 Subject: reviewed by: Johan Dahlin 2005-05-17 Benjamin Otte reviewed by: Johan Dahlin * gobject/gobjectmodule.c: * gobject/pygobject-private.h: * gobject/pygobject.h: * gobject/pygtype.c: (pyg_closure_marshal), (pyg_closure_set_exception_handler): Adds exception handling support to closures, fixes #304357 --- gobject/pygtype.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'gobject/pygtype.c') diff --git a/gobject/pygtype.c b/gobject/pygtype.c index 37acf3f..92b9ec4 100644 --- a/gobject/pygtype.c +++ b/gobject/pygtype.c @@ -846,16 +846,26 @@ pyg_closure_marshal(GClosure *closure, } ret = PyObject_CallObject(pc->callback, params); if (ret == NULL) { - PyErr_Print(); + if (pc->exception_handler) + pc->exception_handler(return_value, n_param_values, param_values); + else + PyErr_Print(); goto out; } - if (return_value) - pyg_value_from_pyobject(return_value, ret); + + if (return_value && pyg_value_from_pyobject(return_value, ret) != 0) { + PyErr_SetString(PyExc_TypeError, + "can't convert return value to desired type"); + + if (pc->exception_handler) + pc->exception_handler(return_value, n_param_values, param_values); + else + PyErr_Print(); + } Py_DECREF(ret); out: Py_DECREF(params); - pyg_gil_state_release(state); } @@ -899,6 +909,28 @@ pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data) return closure; } +/** + * pyg_closure_set_exception_handler: + * @closure: a closure created with pyg_closure_new() + * @handler: the handler to call when an exception occurs or NULL for none + * + * Sets the handler to call when an exception occurs during closure invocation. + * The handler is responsible for providing a proper return value to the + * closure invocation. If @handler is %NULL, the default handler will be used. + * The default handler prints the exception to stderr and doesn't touch the + * closure's return value. + */ +void +pyg_closure_set_exception_handler(GClosure *closure, + PyClosureExceptionHandler handler) +{ + PyGClosure *pygclosure; + + g_return_if_fail(closure != NULL); + + pygclosure = (PyGClosure *)closure; + pygclosure->exception_handler = handler; +} /* -------------- PySignalClassClosure ----------------- */ /* a closure used for the `class closure' of a signal. As this gets * all the info from the first argument to the closure and the -- cgit