1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 1998-2003 James Henstridge
5 * 2004-2008 Johan Dahlin
6 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
7 * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "pygi-error.h"
25 #include "pygi-type.h"
26 #include "pygi-python-compat.h"
27 #include "pygi-util.h"
28 #include "pygi-basictype.h"
31 PyObject *PyGError = NULL;
34 * pygi_error_marshal_to_py:
35 * @error: a pointer to the GError.
37 * Checks to see if @error has been set. If @error has been set, then a
38 * GLib.GError Python exception object is returned (but not raised).
40 * Returns: a GLib.GError Python exception object, or NULL.
43 pygi_error_marshal_to_py (GError **error)
45 PyGILState_STATE state;
47 PyObject *exc_instance;
48 const char *domain = NULL;
50 g_return_val_if_fail(error != NULL, NULL);
55 state = PyGILState_Ensure();
59 if ((*error)->domain) {
60 domain = g_quark_to_string ((*error)->domain);
63 exc_instance = PyObject_CallFunction (exc_type, "ssi",
68 PyGILState_Release(state);
75 * @error: a pointer to the GError.
77 * Checks to see if the GError has been set. If the error has been
78 * set, then the glib.GError Python exception will be raised, and
81 * Returns: True if an error was set.
84 pygi_error_check (GError **error)
86 PyGILState_STATE state;
87 PyObject *exc_instance;
89 g_return_val_if_fail(error != NULL, FALSE);
93 state = PyGILState_Ensure();
95 exc_instance = pygi_error_marshal_to_py (error);
96 PyErr_SetObject(PyGError, exc_instance);
97 Py_DECREF(exc_instance);
100 PyGILState_Release(state);
106 * pygi_error_marshal_from_py:
107 * @pyerr: A Python exception instance.
108 * @error: a standard GLib GError ** output parameter
110 * Converts from a Python implemented GError into a GError.
112 * Returns: TRUE if the conversion was successful, otherwise a Python exception
113 * is set and FALSE is returned.
116 pygi_error_marshal_from_py (PyObject *pyerr, GError **error)
119 gchar *message = NULL;
120 gchar *domain = NULL;
121 gboolean res = FALSE;
122 PyObject *py_message = NULL,
126 if (PyObject_IsInstance (pyerr, PyGError) != 1) {
127 PyErr_Format (PyExc_TypeError, "Must be GLib.Error, not %s",
128 Py_TYPE (pyerr)->tp_name);
132 py_message = PyObject_GetAttrString (pyerr, "message");
134 PyErr_SetString (PyExc_ValueError,
135 "GLib.Error instances must have a 'message' string attribute");
139 if (!pygi_utf8_from_py (py_message, &message))
142 py_domain = PyObject_GetAttrString (pyerr, "domain");
144 PyErr_SetString (PyExc_ValueError,
145 "GLib.Error instances must have a 'domain' string attribute");
149 if (!pygi_utf8_from_py (py_domain, &domain))
152 py_code = PyObject_GetAttrString (pyerr, "code");
154 PyErr_SetString (PyExc_ValueError,
155 "GLib.Error instances must have a 'code' int attribute");
159 if (!pygi_gint_from_py (py_code, &code))
163 g_set_error_literal (error,
164 g_quark_from_string (domain),
171 Py_XDECREF (py_message);
172 Py_XDECREF (py_code);
173 Py_XDECREF (py_domain);
178 * pygi_gerror_exception_check:
179 * @error: a standard GLib GError ** output parameter
181 * Checks to see if a GError exception has been raised, and if so
182 * translates the python exception to a standard GLib GError. If the
183 * raised exception is not a GError then PyErr_Print() is called.
185 * Returns: 0 if no exception has been raised, -1 if it is a
186 * valid glib.GError, -2 otherwise.
189 pygi_gerror_exception_check (GError **error)
192 PyObject *type, *value, *traceback;
193 PyErr_Fetch(&type, &value, &traceback);
196 PyErr_NormalizeException(&type, &value, &traceback);
198 PyErr_Restore(type, value, traceback);
203 !PyErr_GivenExceptionMatches(type,
204 (PyObject *) PyGError)) {
205 PyErr_Restore(type, value, traceback);
210 Py_XDECREF(traceback);
212 if (!pygi_error_marshal_from_py (value, error)) {
223 _pygi_marshal_from_py_gerror (PyGIInvokeState *state,
224 PyGICallableCache *callable_cache,
225 PyGIArgCache *arg_cache,
228 gpointer *cleanup_data)
230 GError *error = NULL;
231 if (pygi_error_marshal_from_py (py_arg, &error)) {
232 arg->v_pointer = error;
233 *cleanup_data = error;
242 _pygi_marshal_from_py_gerror_cleanup (PyGIInvokeState *state,
243 PyGIArgCache *arg_cache,
246 gboolean was_processed)
249 g_error_free ((GError *)data);
254 _pygi_marshal_to_py_gerror (PyGIInvokeState *state,
255 PyGICallableCache *callable_cache,
256 PyGIArgCache *arg_cache,
258 gpointer *cleanup_data)
260 GError *error = arg->v_pointer;
261 PyObject *py_obj = NULL;
263 py_obj = pygi_error_marshal_to_py (&error);
265 if (arg_cache->transfer == GI_TRANSFER_EVERYTHING && error != NULL) {
266 g_error_free (error);
269 if (py_obj != NULL) {
277 pygi_arg_gerror_setup_from_info (PyGIArgCache *arg_cache,
278 GITypeInfo *type_info,
281 PyGIDirection direction)
283 if (!pygi_arg_base_setup (arg_cache, type_info, arg_info, transfer, direction)) {
287 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
288 arg_cache->from_py_marshaller = _pygi_marshal_from_py_gerror;
290 /* Assign cleanup function if we manage memory after call completion. */
291 if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
292 arg_cache->from_py_cleanup = _pygi_marshal_from_py_gerror_cleanup;
296 if (direction & PYGI_DIRECTION_TO_PYTHON) {
297 arg_cache->to_py_marshaller = _pygi_marshal_to_py_gerror;
298 arg_cache->meta_type = PYGI_META_ARG_TYPE_PARENT;
305 pygi_arg_gerror_new_from_info (GITypeInfo *type_info,
308 PyGIDirection direction)
310 gboolean res = FALSE;
311 PyGIArgCache *arg_cache;
313 arg_cache = pygi_arg_cache_alloc ();
315 res = pygi_arg_gerror_setup_from_info (arg_cache,
323 pygi_arg_cache_free (arg_cache);
329 pygerror_from_gvalue (const GValue *value)
331 GError *gerror = (GError *) g_value_get_boxed (value);
332 PyObject *pyerr = pygi_error_marshal_to_py (&gerror);
341 pygerror_to_gvalue (GValue *value, PyObject *pyerror)
343 GError *gerror = NULL;
345 if (pygi_error_marshal_from_py (pyerror, &gerror)) {
346 g_value_take_boxed (value, gerror);
354 * Returns 0 on success, or -1 and sets an exception.
357 pygi_error_register_types (PyObject *module)
359 PyObject *error_module = pygi_import_module ("gi._error");
364 /* Stash a reference to the Python implemented gi._error.GError. */
365 PyGError = PyObject_GetAttrString (error_module, "GError");
366 Py_DECREF (error_module);
367 if (PyGError == NULL)
370 pyg_register_gtype_custom (G_TYPE_ERROR,
371 pygerror_from_gvalue,