[pygtk] GError-Exception support and exception handling in GOption

2006-05-25 Thread Johannes Hölzl
Hi,

the gobject.option implementation of GOption currently doesn't handle
errors when for example an option gets the wrong argument (for example:
--number=text). 

To support exception in gobject.Option i implemented:

/**
 * Checks if a GError exception occurred in python and set the GError.
 * If the exception is not a GError or the GError exception has no
 * domain, code and message attributes the exception is printed.
 *
 * Ensures the GIL state.
 *
 * Returns: True if a python-exception was set and this exception was a 
 *  correct GError-Exception.
 */
gboolean
pyg_set_gerror_from_exception (GError **error_dest)

To use this function, the python-code must create a gobject.GError()
object and add domain, code and message attributes manually, for
example:

err = gobject.GError(message)
err.domain = gobject.OPTION_ERROR
err.code = gobject.OPTION_ERROR_BAD_VALUE
err.message = Wrong option ...
raise err

Or should i add a full GError-class? 

I didn't look, but are there other places in pygtk where a
GError-Exception isn't translated into GError?

The attached patch adds this function and the exception handling in
GOption.

best regards,
Johannes Hölzl

PS: Are two patches, one with only pyg_set_gerror_from_exception
implementation and another with exception support in GOption preferred?

Index: ChangeLog
===
RCS file: /cvs/gnome/gnome-python/pygobject/ChangeLog,v
retrieving revision 1.43
diff -u -r1.43 ChangeLog
--- ChangeLog	20 May 2006 13:45:35 -	1.43
+++ ChangeLog	25 May 2006 18:25:52 -
@@ -1,3 +1,16 @@
+2006-05-24  Johannes Hölzl  [EMAIL PROTECTED]
+
+	* gobject/gobjectmodule.c (pyg_exception_to_gerror):
+	Added function to convert gobject.GError-exception into GError.
+	
+	* gobject/gobjectmodule.c (init_gobjectmodule):
+	* gobject/pygoptiongroup.c (arg_func): 
+	* gobject/option.py (OptionParser._parse_args, 
+	OptionGroup._to_goptiongroup):
+	* tests/test_option.py: 
+	Added conversion of Python exceptions
+	into GErrors and vice versa.
+
 2006-05-20  Yevgen Muntyan  [EMAIL PROTECTED]
 
 	reviewed by: Gustavo Carneiro
Index: gobject/gobjectmodule.c
===
RCS file: /cvs/gnome/gnome-python/pygobject/gobject/gobjectmodule.c,v
retrieving revision 1.219
diff -u -r1.219 gobjectmodule.c
--- gobject/gobjectmodule.c	7 May 2006 21:32:21 -	1.219
+++ gobject/gobjectmodule.c	25 May 2006 18:25:57 -
@@ -2799,6 +2799,66 @@
 return FALSE;
 }
 
+/**
+ * Checks if a GError exception occurred in python and set the GError.
+ * If the exception is not a GError or the GError exception has no
+ * domain, code and message attributes the exception is printed.
+ *
+ * Ensures the GIL state.
+ *
+ * Returns: True if a python-exception was set and this exception was a 
+ *  correct GError-Exception.
+ */
+gboolean
+pyg_set_gerror_from_exception (GError **error_dest)
+{
+PyObject *exception_type, *exception_value, *exception_tb;
+GQuark domain;
+gint code;
+PyObject *value = NULL;
+PyGILState_STATE state = pyg_gil_state_ensure();
+
+g_assert(error_dest != NULL);
+g_assert(*error_dest == NULL);
+
+PyErr_Fetch(exception_type, exception_value, exception_tb);
+if (!exception_type) return FALSE;
+if (!PyErr_GivenExceptionMatches(exception_type, gerror_exc)) goto failed;
+if (!exception_value) goto failed;
+
+if (!PyObject_HasAttrString(exception_value, domain)) goto failed;
+value = PyObject_GetAttrString(exception_value, domain);
+if (!PyString_Check(value)) goto failed;
+domain = g_quark_from_string(PyString_AsString(value));
+Py_CLEAR(value);
+
+if (!PyObject_HasAttrString(exception_value, code)) goto failed;
+value = PyObject_GetAttrString(exception_value, code);
+if (!PyInt_Check(value)) goto failed;
+code = PyInt_AsLong(value);
+Py_CLEAR(value);
+
+if (!PyObject_HasAttrString(exception_value, message)) goto failed;
+value = PyObject_GetAttrString(exception_value, message);
+if (!PyString_Check(value)) goto failed;
+*error_dest = g_error_new_literal(domain, code, PyString_AsString(value));
+Py_CLEAR(value);
+
+Py_XDECREF(exception_tb);
+Py_XDECREF(exception_value);
+Py_DECREF(exception_type);
+
+pyg_gil_state_release(state);
+return TRUE;
+
+failed:
+Py_XDECREF(value);
+
+PyErr_Restore(exception_type, exception_value, exception_tb);
+PyErr_Print();
+pyg_gil_state_release(state);
+return FALSE;
+}
 
 static PyObject *
 _pyg_strv_from_gvalue(const GValue *value)
@@ -3106,6 +3166,7 @@
   pyg_constant_strip_prefix,
 
   pyg_error_check,
+  pyg_set_gerror_from_exception,
 
   pyg_set_thread_block_funcs,
   (PyGThreadBlockFunc)0, /* block_threads */
@@ -3322,6 +3383,8 @@
 #undef addint
   
 PyModule_AddStringConstant(m, OPTION_REMAINING, G_OPTION_REMAINING);
+
+PyModule_AddStringConstant(m, 

Re: [pygtk] GError-Exception support and exception handling in GOption

2006-05-25 Thread Johan Dahlin
 the gobject.option implementation of GOption currently doesn't handle
 errors when for example an option gets the wrong argument (for example:
 --number=text). 
 
 To support exception in gobject.Option i implemented:

Cool. Seems nice.

 The attached patch adds this function and the exception handling in
 GOption.

Please, attach patches in bugzilla or they will be forgotten.

-- 
Johan Dahlin [EMAIL PROTECTED]
Async Open Source
___
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/