release 3.27.0
[pygobject.git] / gi / pygi-object.c
blob8fd8ee0f921b78aaa8c1adfa589358dbdcf103db
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/>.
21 #include <Python.h>
22 #include <glib.h>
23 #include <pyglib-python-compat.h>
25 #include "pygi-object.h"
26 #include "pygobject-object.h"
27 #include "pygparamspec.h"
30 * GObject from Python
33 typedef gboolean (*PyGIObjectMarshalFromPyFunc) (PyObject *py_arg,
34 GIArgument *arg,
35 GITransfer transfer);
37 /* _pygi_marshal_from_py_gobject:
38 * py_arg: (in):
39 * arg: (out):
41 static gboolean
42 _pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/
43 GIArgument *arg, /*out*/
44 GITransfer transfer) {
45 GObject *gobj;
47 if (py_arg == Py_None) {
48 arg->v_pointer = NULL;
49 return TRUE;
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));
56 Py_DECREF (repr);
57 return FALSE;
60 gobj = pygobject_get (py_arg);
61 if (gobj == NULL) {
62 PyErr_Format(PyExc_RuntimeError, "object at %p of type %s is not initialized",
63 py_arg, Py_TYPE(py_arg)->tp_name);
64 return FALSE;
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.
71 g_object_ref (gobj);
74 arg->v_pointer = gobj;
75 return TRUE;
78 /* pygi_arg_gobject_out_arg_from_py:
79 * py_arg: (in):
80 * arg: (out):
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.
85 gboolean
86 pygi_arg_gobject_out_arg_from_py (PyObject *py_arg, /*in*/
87 GIArgument *arg, /*out*/
88 GITransfer transfer) {
89 GObject *gobj;
90 if (!_pygi_marshal_from_py_gobject (py_arg, arg, transfer)) {
91 return FALSE;
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.
105 g_object_ref (gobj);
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);
115 } else {
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));
121 Py_DECREF (repr);
122 if (PyErr_WarnEx (PyExc_RuntimeWarning, msg, 2)) {
123 g_free (msg);
124 return FALSE;
126 g_free (msg);
130 return TRUE;
133 static gboolean
134 _pygi_marshal_from_py_interface_object (PyGIInvokeState *state,
135 PyGICallableCache *callable_cache,
136 PyGIArgCache *arg_cache,
137 PyObject *py_arg,
138 GIArgument *arg,
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;
146 return TRUE;
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))) {
153 gboolean res;
154 res = func (py_arg, arg, arg_cache->transfer);
155 *cleanup_data = arg->v_pointer;
156 return res;
158 } else {
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) : "",
165 module ? "." : "",
166 py_arg->ob_type->tp_name);
167 if (module)
168 Py_DECREF (module);
169 return FALSE;
173 static gboolean
174 _pygi_marshal_from_py_called_from_c_interface_object (PyGIInvokeState *state,
175 PyGICallableCache *callable_cache,
176 PyGIArgCache *arg_cache,
177 PyObject *py_arg,
178 GIArgument *arg,
179 gpointer *cleanup_data)
181 return _pygi_marshal_from_py_interface_object (state,
182 callable_cache,
183 arg_cache,
184 py_arg,
185 arg,
186 cleanup_data,
187 pygi_arg_gobject_out_arg_from_py);
190 static gboolean
191 _pygi_marshal_from_py_called_from_py_interface_object (PyGIInvokeState *state,
192 PyGICallableCache *callable_cache,
193 PyGIArgCache *arg_cache,
194 PyObject *py_arg,
195 GIArgument *arg,
196 gpointer *cleanup_data)
198 return _pygi_marshal_from_py_interface_object (state,
199 callable_cache,
200 arg_cache,
201 py_arg,
202 arg,
203 cleanup_data,
204 _pygi_marshal_from_py_gobject);
207 static void
208 _pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state,
209 PyGIArgCache *arg_cache,
210 PyObject *py_arg,
211 gpointer data,
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));
223 * GObject to Python
226 PyObject *
227 pygi_arg_gobject_to_py (GIArgument *arg, GITransfer transfer) {
228 PyObject *pyobj;
230 if (arg->v_pointer == NULL) {
231 pyobj = Py_None;
232 Py_INCREF (pyobj);
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);
239 } else {
240 pyobj = pygobject_new_full (arg->v_pointer,
241 /*steal=*/ transfer == GI_TRANSFER_EVERYTHING,
242 /*type=*/ NULL);
245 return pyobj;
248 PyObject *
249 pygi_arg_gobject_to_py_called_from_c (GIArgument *arg,
250 GITransfer transfer)
252 PyObject *object;
254 /* HACK:
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);
271 } else {
272 object = pygi_arg_gobject_to_py (arg, transfer);
275 return object;
278 static PyObject *
279 _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter (PyGIInvokeState *state,
280 PyGICallableCache *callable_cache,
281 PyGIArgCache *arg_cache,
282 GIArgument *arg)
284 return pygi_arg_gobject_to_py_called_from_c (arg, arg_cache->transfer);
287 static PyObject *
288 _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter (PyGIInvokeState *state,
289 PyGICallableCache *callable_cache,
290 PyGIArgCache *arg_cache,
291 GIArgument *arg)
293 return pygi_arg_gobject_to_py (arg, arg_cache->transfer);
296 static void
297 _pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state,
298 PyGIArgCache *arg_cache,
299 PyObject *dummy,
300 gpointer data,
301 gboolean was_processed)
303 /* If we error out and the object is not marshalled into a PyGObject
304 we must take care of removing the ref */
305 if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
306 g_object_unref (G_OBJECT(data));
309 static gboolean
310 pygi_arg_gobject_setup_from_info (PyGIArgCache *arg_cache,
311 GITypeInfo *type_info,
312 GIArgInfo *arg_info,
313 GITransfer transfer,
314 PyGIDirection direction,
315 PyGICallableCache *callable_cache)
317 /* NOTE: usage of pygi_arg_interface_new_from_info already calls
318 * pygi_arg_interface_setup so no need to do it here.
321 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
322 if (callable_cache->calling_context == PYGI_CALLING_CONTEXT_IS_FROM_C) {
323 arg_cache->from_py_marshaller = _pygi_marshal_from_py_called_from_c_interface_object;
324 } else {
325 arg_cache->from_py_marshaller = _pygi_marshal_from_py_called_from_py_interface_object;
328 arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
331 if (direction & PYGI_DIRECTION_TO_PYTHON) {
332 if (callable_cache->calling_context == PYGI_CALLING_CONTEXT_IS_FROM_C) {
333 arg_cache->to_py_marshaller = _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter;
334 } else {
335 arg_cache->to_py_marshaller = _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter;
338 arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
341 return TRUE;
344 PyGIArgCache *
345 pygi_arg_gobject_new_from_info (GITypeInfo *type_info,
346 GIArgInfo *arg_info,
347 GITransfer transfer,
348 PyGIDirection direction,
349 GIInterfaceInfo *iface_info,
350 PyGICallableCache *callable_cache)
352 gboolean res = FALSE;
353 PyGIArgCache *cache = NULL;
355 cache = pygi_arg_interface_new_from_info (type_info,
356 arg_info,
357 transfer,
358 direction,
359 iface_info);
360 if (cache == NULL)
361 return NULL;
363 res = pygi_arg_gobject_setup_from_info (cache,
364 type_info,
365 arg_info,
366 transfer,
367 direction,
368 callable_cache);
369 if (res) {
370 return cache;
371 } else {
372 pygi_arg_cache_free (cache);
373 return NULL;