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
);
62 PyErr_Format(PyExc_RuntimeError
, "object at %p of type %s is not initialized",
63 py_arg
, Py_TYPE(py_arg
)->tp_name
);
67 if (transfer
== GI_TRANSFER_EVERYTHING
) {
68 /* For transfer everything, add a new ref that the callee will take ownership of.
69 * Pythons existing ref to the GObject will be managed with the PyGObject wrapper.
74 arg
->v_pointer
= gobj
;
78 /* pygi_arg_gobject_out_arg_from_py:
82 * A specialization for marshaling Python GObjects used for out/return values
83 * from a Python implemented vfuncs, signals, or an assignment to a GObject property.
86 pygi_arg_gobject_out_arg_from_py (PyObject
*py_arg
, /*in*/
87 GIArgument
*arg
, /*out*/
88 GITransfer transfer
) {
90 if (!_pygi_marshal_from_py_gobject (py_arg
, arg
, transfer
)) {
94 /* HACK: At this point the basic marshaling of the GObject was successful
95 * but we add some special case hacks for vfunc returns due to buggy APIs:
96 * https://bugzilla.gnome.org/show_bug.cgi?id=693393
98 gobj
= arg
->v_pointer
;
99 if (py_arg
->ob_refcnt
== 1 && gobj
->ref_count
== 1) {
100 /* If both object ref counts are only 1 at this point (the reference held
101 * in a return tuple), we assume the GObject will be free'd before reaching
102 * its target and become invalid. So instead of getting invalid object errors
103 * we add a new GObject ref.
107 if (((PyGObject
*)py_arg
)->private_flags
.flags
& PYGOBJECT_GOBJECT_WAS_FLOATING
) {
109 * We want to re-float instances that were floating and the Python
110 * wrapper assumed ownership. With the additional caveat that there
111 * are not any strong references beyond the return tuple.
113 g_object_force_floating (gobj
);
116 PyObject
*repr
= PyObject_Repr (py_arg
);
117 gchar
*msg
= g_strdup_printf ("Expecting to marshal a borrowed reference for %s, "
118 "but nothing in Python is holding a reference to this object. "
119 "See: https://bugzilla.gnome.org/show_bug.cgi?id=687522",
120 PYGLIB_PyUnicode_AsString(repr
));
122 if (PyErr_WarnEx (PyExc_RuntimeWarning
, msg
, 2)) {
134 _pygi_marshal_from_py_interface_object (PyGIInvokeState
*state
,
135 PyGICallableCache
*callable_cache
,
136 PyGIArgCache
*arg_cache
,
139 gpointer
*cleanup_data
,
140 PyGIObjectMarshalFromPyFunc func
)
142 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
144 if (py_arg
== Py_None
) {
145 arg
->v_pointer
= NULL
;
149 if (PyObject_IsInstance (py_arg
, iface_cache
->py_type
) ||
150 (pygobject_check (py_arg
, &PyGObject_Type
) &&
151 g_type_is_a (G_OBJECT_TYPE (pygobject_get (py_arg
)), iface_cache
->g_type
))) {
154 res
= func (py_arg
, arg
, arg_cache
->transfer
);
155 *cleanup_data
= arg
->v_pointer
;
159 PyObject
*module
= PyObject_GetAttrString(py_arg
, "__module__");
161 PyErr_Format (PyExc_TypeError
, "argument %s: Expected %s, but got %s%s%s",
162 arg_cache
->arg_name
? arg_cache
->arg_name
: "self",
163 ( (PyGIInterfaceCache
*)arg_cache
)->type_name
,
164 module
? PYGLIB_PyUnicode_AsString(module
) : "",
166 py_arg
->ob_type
->tp_name
);
174 _pygi_marshal_from_py_called_from_c_interface_object (PyGIInvokeState
*state
,
175 PyGICallableCache
*callable_cache
,
176 PyGIArgCache
*arg_cache
,
179 gpointer
*cleanup_data
)
181 return _pygi_marshal_from_py_interface_object (state
,
187 pygi_arg_gobject_out_arg_from_py
);
191 _pygi_marshal_from_py_called_from_py_interface_object (PyGIInvokeState
*state
,
192 PyGICallableCache
*callable_cache
,
193 PyGIArgCache
*arg_cache
,
196 gpointer
*cleanup_data
)
198 return _pygi_marshal_from_py_interface_object (state
,
204 _pygi_marshal_from_py_gobject
);
208 _pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState
*state
,
209 PyGIArgCache
*arg_cache
,
212 gboolean was_processed
)
214 /* If we processed the parameter but fail before invoking the method,
215 we need to remove the ref we added */
216 if (was_processed
&& state
->failed
&& data
!= NULL
&&
217 arg_cache
->transfer
== GI_TRANSFER_EVERYTHING
)
218 g_object_unref (G_OBJECT(data
));
227 pygi_arg_gobject_to_py (GIArgument
*arg
, GITransfer transfer
) {
230 if (arg
->v_pointer
== NULL
) {
234 } else if (G_IS_PARAM_SPEC(arg
->v_pointer
)) {
235 pyobj
= pyg_param_spec_new (arg
->v_pointer
);
236 if (transfer
== GI_TRANSFER_EVERYTHING
)
237 g_param_spec_unref (arg
->v_pointer
);
240 pyobj
= pygobject_new_full (arg
->v_pointer
,
241 /*steal=*/ transfer
== GI_TRANSFER_EVERYTHING
,
249 pygi_arg_gobject_to_py_called_from_c (GIArgument
*arg
,
255 * The following hack is to work around GTK+ sending signals which
256 * contain floating widgets in them. This assumes control of how
257 * references are added by the PyGObject wrapper and avoids the sink
258 * behavior by explicitly passing GI_TRANSFER_EVERYTHING as the transfer
259 * mode and then re-forcing the object as floating afterwards.
261 * See: https://bugzilla.gnome.org/show_bug.cgi?id=693400
263 if (arg
->v_pointer
!= NULL
&&
264 transfer
== GI_TRANSFER_NOTHING
&&
265 !G_IS_PARAM_SPEC (arg
->v_pointer
) &&
266 g_object_is_floating (arg
->v_pointer
)) {
268 g_object_ref (arg
->v_pointer
);
269 object
= pygi_arg_gobject_to_py (arg
, GI_TRANSFER_EVERYTHING
);
270 g_object_force_floating (arg
->v_pointer
);
272 object
= pygi_arg_gobject_to_py (arg
, transfer
);
279 _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter (PyGIInvokeState
*state
,
280 PyGICallableCache
*callable_cache
,
281 PyGIArgCache
*arg_cache
,
283 gpointer
*cleanup_data
)
285 return pygi_arg_gobject_to_py_called_from_c (arg
, arg_cache
->transfer
);
289 _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter (PyGIInvokeState
*state
,
290 PyGICallableCache
*callable_cache
,
291 PyGIArgCache
*arg_cache
,
293 gpointer
*cleanup_data
)
295 return pygi_arg_gobject_to_py (arg
, arg_cache
->transfer
);
299 _pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState
*state
,
300 PyGIArgCache
*arg_cache
,
301 gpointer cleanup_data
,
303 gboolean was_processed
)
305 /* If we error out and the object is not marshalled into a PyGObject
306 we must take care of removing the ref */
307 if (!was_processed
&& arg_cache
->transfer
== GI_TRANSFER_EVERYTHING
)
308 g_object_unref (G_OBJECT(data
));
312 pygi_arg_gobject_setup_from_info (PyGIArgCache
*arg_cache
,
313 GITypeInfo
*type_info
,
316 PyGIDirection direction
,
317 PyGICallableCache
*callable_cache
)
319 /* NOTE: usage of pygi_arg_interface_new_from_info already calls
320 * pygi_arg_interface_setup so no need to do it here.
323 if (direction
& PYGI_DIRECTION_FROM_PYTHON
) {
324 if (callable_cache
->calling_context
== PYGI_CALLING_CONTEXT_IS_FROM_C
) {
325 arg_cache
->from_py_marshaller
= _pygi_marshal_from_py_called_from_c_interface_object
;
327 arg_cache
->from_py_marshaller
= _pygi_marshal_from_py_called_from_py_interface_object
;
330 arg_cache
->from_py_cleanup
= _pygi_marshal_cleanup_from_py_interface_object
;
333 if (direction
& PYGI_DIRECTION_TO_PYTHON
) {
334 if (callable_cache
->calling_context
== PYGI_CALLING_CONTEXT_IS_FROM_C
) {
335 arg_cache
->to_py_marshaller
= _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter
;
337 arg_cache
->to_py_marshaller
= _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter
;
340 arg_cache
->to_py_cleanup
= _pygi_marshal_cleanup_to_py_interface_object
;
347 pygi_arg_gobject_new_from_info (GITypeInfo
*type_info
,
350 PyGIDirection direction
,
351 GIInterfaceInfo
*iface_info
,
352 PyGICallableCache
*callable_cache
)
354 gboolean res
= FALSE
;
355 PyGIArgCache
*cache
= NULL
;
357 cache
= pygi_arg_interface_new_from_info (type_info
,
365 res
= pygi_arg_gobject_setup_from_info (cache
,
374 pygi_arg_cache_free (cache
);