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
,