1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * vim: tabstop=4 shiftwidth=4 expandtab
4 * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5 * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 #include <pyglib-python-compat.h>
25 #include "pygi-object.h"
26 #include "pygobject-object.h"
27 #include "pygparamspec.h"
33 typedef gboolean (*PyGIObjectMarshalFromPyFunc) (PyObject *py_arg,
37 /* _pygi_marshal_from_py_gobject:
42 _pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/
43 GIArgument *arg, /*out*/
44 GITransfer transfer) {
47 if (py_arg == Py_None) {
48 arg->v_pointer = NULL;
52 if (!pygobject_check (py_arg, &PyGObject_Type)) {
53 PyObject *repr = PyObject_Repr (py_arg);
54 PyErr_Format(PyExc_TypeError, "expected GObject but got %s",
55 PYGLIB_PyUnicode_AsString (repr));
60 gobj = pygobject_get (py_arg);
61 if (transfer == GI_TRANSFER_EVERYTHING) {
62 /* For transfer everything, add a new ref that the callee will take ownership of.
63 * Pythons existing ref to the GObject will be managed with the PyGObject wrapper.
68 arg->v_pointer = gobj;
72 /* pygi_arg_gobject_out_arg_from_py:
76 * A specialization for marshaling Python GObjects used for out/return values
77 * from a Python implemented vfuncs, signals, or an assignment to a GObject property.
80 pygi_arg_gobject_out_arg_from_py (PyObject *py_arg, /*in*/
81 GIArgument *arg, /*out*/
82 GITransfer transfer) {
84 if (!_pygi_marshal_from_py_gobject (py_arg, arg, transfer)) {
88 /* HACK: At this point the basic marshaling of the GObject was successful
89 * but we add some special case hacks for vfunc returns due to buggy APIs:
90 * https://bugzilla.gnome.org/show_bug.cgi?id=693393
92 gobj = arg->v_pointer;
93 if (py_arg->ob_refcnt == 1 && gobj->ref_count == 1) {
94 /* If both object ref counts are only 1 at this point (the reference held
95 * in a return tuple), we assume the GObject will be free'd before reaching
96 * its target and become invalid. So instead of getting invalid object errors
97 * we add a new GObject ref.
101 if (((PyGObject *)py_arg)->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) {
103 * We want to re-float instances that were floating and the Python
104 * wrapper assumed ownership. With the additional caveat that there
105 * are not any strong references beyond the return tuple.
107 g_object_force_floating (gobj);
110 PyObject *repr = PyObject_Repr (py_arg);
111 gchar *msg = g_strdup_printf ("Expecting to marshal a borrowed reference for %s, "
112 "but nothing in Python is holding a reference to this object. "
113 "See: https://bugzilla.gnome.org/show_bug.cgi?id=687522",
114 PYGLIB_PyUnicode_AsString(repr));
116 if (PyErr_WarnEx (PyExc_RuntimeWarning, msg, 2)) {
128 _pygi_marshal_from_py_interface_object (PyGIInvokeState *state,
129 PyGICallableCache *callable_cache,
130 PyGIArgCache *arg_cache,
133 gpointer *cleanup_data,
134 PyGIObjectMarshalFromPyFunc func)
136 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
138 if (py_arg == Py_None) {
139 arg->v_pointer = NULL;
143 if (PyObject_IsInstance (py_arg, iface_cache->py_type) ||
144 (pygobject_check (py_arg, &PyGObject_Type) &&
145 g_type_is_a (G_OBJECT_TYPE (pygobject_get (py_arg)), iface_cache->g_type))) {
148 res = func (py_arg, arg, arg_cache->transfer);
149 *cleanup_data = arg->v_pointer;
153 PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
155 PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
156 arg_cache->arg_name ? arg_cache->arg_name : "self",
157 ( (PyGIInterfaceCache *)arg_cache)->type_name,
158 module ? PYGLIB_PyUnicode_AsString(module) : "",
160 py_arg->ob_type->tp_name);
168 _pygi_marshal_from_py_called_from_c_interface_object (PyGIInvokeState *state,
169 PyGICallableCache *callable_cache,
170 PyGIArgCache *arg_cache,
173 gpointer *cleanup_data)
175 return _pygi_marshal_from_py_interface_object (state,
181 pygi_arg_gobject_out_arg_from_py);
185 _pygi_marshal_from_py_called_from_py_interface_object (PyGIInvokeState *state,
186 PyGICallableCache *callable_cache,
187 PyGIArgCache *arg_cache,
190 gpointer *cleanup_data)
192 return _pygi_marshal_from_py_interface_object (state,
198 _pygi_marshal_from_py_gobject);
202 _pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state,
203 PyGIArgCache *arg_cache,
206 gboolean was_processed)
208 /* If we processed the parameter but fail before invoking the method,
209 we need to remove the ref we added */
210 if (was_processed && state->failed && data != NULL &&
211 arg_cache->transfer == GI_TRANSFER_EVERYTHING)
212 g_object_unref (G_OBJECT(data));
221 pygi_arg_gobject_to_py (GIArgument *arg, GITransfer transfer) {
224 if (arg->v_pointer == NULL) {
228 } else if (G_IS_PARAM_SPEC(arg->v_pointer)) {
229 pyobj = pyg_param_spec_new (arg->v_pointer);
230 if (transfer == GI_TRANSFER_EVERYTHING)
231 g_param_spec_unref (arg->v_pointer);
234 pyobj = pygobject_new_full (arg->v_pointer,
235 /*steal=*/ transfer == GI_TRANSFER_EVERYTHING,
243 pygi_arg_gobject_to_py_called_from_c (GIArgument *arg,
249 * The following hack is to work around GTK+ sending signals which
250 * contain floating widgets in them. This assumes control of how
251 * references are added by the PyGObject wrapper and avoids the sink
252 * behavior by explicitly passing GI_TRANSFER_EVERYTHING as the transfer
253 * mode and then re-forcing the object as floating afterwards.
255 * See: https://bugzilla.gnome.org/show_bug.cgi?id=693400
257 if (arg->v_pointer != NULL &&
258 transfer == GI_TRANSFER_NOTHING &&
259 !G_IS_PARAM_SPEC (arg->v_pointer) &&
260 g_object_is_floating (arg->v_pointer)) {
262 g_object_ref (arg->v_pointer);
263 object = pygi_arg_gobject_to_py (arg, GI_TRANSFER_EVERYTHING);
264 g_object_force_floating (arg->v_pointer);
266 object = pygi_arg_gobject_to_py (arg, transfer);
273 _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter (PyGIInvokeState *state,
274 PyGICallableCache *callable_cache,
275 PyGIArgCache *arg_cache,
278 return pygi_arg_gobject_to_py_called_from_c (arg, arg_cache->transfer);
282 _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter (PyGIInvokeState *state,
283 PyGICallableCache *callable_cache,
284 PyGIArgCache *arg_cache,
287 return pygi_arg_gobject_to_py (arg, arg_cache->transfer);
291 _pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state,
292 PyGIArgCache *arg_cache,
295 gboolean was_processed)
297 /* If we error out and the object is not marshalled into a PyGObject
298 we must take care of removing the ref */
299 if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
300 g_object_unref (G_OBJECT(data));
304 pygi_arg_gobject_setup_from_info (PyGIArgCache *arg_cache,
305 GITypeInfo *type_info,
308 PyGIDirection direction,
309 PyGICallableCache *callable_cache)
311 /* NOTE: usage of pygi_arg_interface_new_from_info already calls
312 * pygi_arg_interface_setup so no need to do it here.
315 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
316 if (callable_cache->calling_context == PYGI_CALLING_CONTEXT_IS_FROM_C) {
317 arg_cache->from_py_marshaller = _pygi_marshal_from_py_called_from_c_interface_object;
319 arg_cache->from_py_marshaller = _pygi_marshal_from_py_called_from_py_interface_object;
322 arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
325 if (direction & PYGI_DIRECTION_TO_PYTHON) {
326 if (callable_cache->calling_context == PYGI_CALLING_CONTEXT_IS_FROM_C) {
327 arg_cache->to_py_marshaller = _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter;
329 arg_cache->to_py_marshaller = _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter;
332 arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
339 pygi_arg_gobject_new_from_info (GITypeInfo *type_info,
342 PyGIDirection direction,
343 GIInterfaceInfo *iface_info,
344 PyGICallableCache *callable_cache)
346 gboolean res = FALSE;
347 PyGIArgCache *cache = NULL;
349 cache = pygi_arg_interface_new_from_info (type_info,
357 res = pygi_arg_gobject_setup_from_info (cache,
366 pygi_arg_cache_free (cache);