a082992fe932e456089592d3cc986e7f6dc747d5
[platform/upstream/python-gobject.git] / gi / pygi-object.c
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2  * vim: tabstop=4 shiftwidth=4 expandtab
3  *
4  * Copyright (C) 2011 John (J5) Palmieri <johnp@redhat.com>
5  * Copyright (C) 2014 Simon Feltman <sfeltman@gnome.org>
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <Python.h>
22 #include <glib.h>
23 #include <pyglib-python-compat.h>
24
25 #include "pygi-object.h"
26 #include "pygi-private.h"
27 #include "pygparamspec.h"
28
29 /*
30  * GObject from Python
31  */
32
33 typedef gboolean (*PyGIObjectMarshalFromPyFunc) (PyObject *py_arg,
34                                                  GIArgument *arg,
35                                                  GITransfer transfer);
36
37 /* _pygi_marshal_from_py_gobject:
38  * py_arg: (in):
39  * arg: (out):
40  */
41 static gboolean
42 _pygi_marshal_from_py_gobject (PyObject *py_arg, /*in*/
43                                GIArgument *arg,  /*out*/
44                                GITransfer transfer) {
45     GObject *gobj;
46
47     if (py_arg == Py_None) {
48         arg->v_pointer = NULL;
49         return TRUE;
50     }
51
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;
58     }
59
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.
64          */
65         g_object_ref (gobj);
66     }
67
68     arg->v_pointer = gobj;
69     return TRUE;
70 }
71
72 /* pygi_arg_gobject_out_arg_from_py:
73  * py_arg: (in):
74  * arg: (out):
75  *
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.
78  */
79 gboolean
80 pygi_arg_gobject_out_arg_from_py (PyObject *py_arg, /*in*/
81                                   GIArgument *arg,  /*out*/
82                                   GITransfer transfer) {
83     GObject *gobj;
84     if (!_pygi_marshal_from_py_gobject (py_arg, arg, transfer)) {
85         return FALSE;
86     }
87
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
91      */
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.
98          */
99         g_object_ref (gobj);
100
101         if (((PyGObject *)py_arg)->private_flags.flags & PYGOBJECT_GOBJECT_WAS_FLOATING) {
102             /*
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.
106              */
107             g_object_force_floating (gobj);
108
109         } else {
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));
115             Py_DECREF (repr);
116             if (PyErr_WarnEx (PyExc_RuntimeWarning, msg, 2)) {
117                 g_free (msg);
118                 return FALSE;
119             }
120             g_free (msg);
121         }
122     }
123
124     return TRUE;
125 }
126
127 static gboolean
128 _pygi_marshal_from_py_interface_object (PyGIInvokeState             *state,
129                                         PyGICallableCache           *callable_cache,
130                                         PyGIArgCache                *arg_cache,
131                                         PyObject                    *py_arg,
132                                         GIArgument                  *arg,
133                                         gpointer                    *cleanup_data,
134                                         PyGIObjectMarshalFromPyFunc  func)
135 {
136     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
137
138     if (py_arg == Py_None) {
139         arg->v_pointer = NULL;
140         return TRUE;
141     }
142
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))) {
146
147         gboolean res;
148         res = func (py_arg, arg, arg_cache->transfer);
149         *cleanup_data = arg->v_pointer;
150         return res;
151
152     } else {
153         PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
154
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) : "",
159                       module ? "." : "",
160                       py_arg->ob_type->tp_name);
161         if (module)
162             Py_DECREF (module);
163         return FALSE;
164     }
165 }
166
167 static gboolean
168 _pygi_marshal_from_py_called_from_c_interface_object (PyGIInvokeState   *state,
169                                                       PyGICallableCache *callable_cache,
170                                                       PyGIArgCache      *arg_cache,
171                                                       PyObject          *py_arg,
172                                                       GIArgument        *arg,
173                                                       gpointer          *cleanup_data)
174 {
175     return _pygi_marshal_from_py_interface_object (state,
176                                                    callable_cache,
177                                                    arg_cache,
178                                                    py_arg,
179                                                    arg,
180                                                    cleanup_data,
181                                                    pygi_arg_gobject_out_arg_from_py);
182 }
183
184 static gboolean
185 _pygi_marshal_from_py_called_from_py_interface_object (PyGIInvokeState   *state,
186                                                        PyGICallableCache *callable_cache,
187                                                        PyGIArgCache      *arg_cache,
188                                                        PyObject          *py_arg,
189                                                        GIArgument        *arg,
190                                                        gpointer          *cleanup_data)
191 {
192     return _pygi_marshal_from_py_interface_object (state,
193                                                    callable_cache,
194                                                    arg_cache,
195                                                    py_arg,
196                                                    arg,
197                                                    cleanup_data,
198                                                    _pygi_marshal_from_py_gobject);
199 }
200
201 static void
202 _pygi_marshal_cleanup_from_py_interface_object (PyGIInvokeState *state,
203                                                 PyGIArgCache    *arg_cache,
204                                                 PyObject        *py_arg,
205                                                 gpointer         data,
206                                                 gboolean         was_processed)
207 {
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));
213 }
214
215
216 /*
217  * GObject to Python
218  */
219
220 PyObject *
221 pygi_arg_gobject_to_py (GIArgument *arg, GITransfer transfer) {
222     PyObject *pyobj;
223
224     if (arg->v_pointer == NULL) {
225         pyobj = Py_None;
226         Py_INCREF (pyobj);
227
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);
232
233     } else {
234          pyobj = pygobject_new_full (arg->v_pointer,
235                                      /*steal=*/ transfer == GI_TRANSFER_EVERYTHING,
236                                      /*type=*/  NULL);
237     }
238
239     return pyobj;
240 }
241
242 PyObject *
243 pygi_arg_gobject_to_py_called_from_c (GIArgument *arg,
244                                       GITransfer  transfer)
245 {
246     PyObject *object;
247
248     /* HACK:
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.
254      *
255      * See: https://bugzilla.gnome.org/show_bug.cgi?id=693400
256      */
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)) {
261
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);
265     } else {
266         object = pygi_arg_gobject_to_py (arg, transfer);
267     }
268
269     return object;
270 }
271
272 static PyObject *
273 _pygi_marshal_to_py_called_from_c_interface_object_cache_adapter (PyGIInvokeState   *state,
274                                                                   PyGICallableCache *callable_cache,
275                                                                   PyGIArgCache      *arg_cache,
276                                                                   GIArgument        *arg)
277 {
278     return pygi_arg_gobject_to_py_called_from_c (arg, arg_cache->transfer);
279 }
280
281 static PyObject *
282 _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter (PyGIInvokeState   *state,
283                                                                    PyGICallableCache *callable_cache,
284                                                                    PyGIArgCache      *arg_cache,
285                                                                    GIArgument        *arg)
286 {
287     return pygi_arg_gobject_to_py (arg, arg_cache->transfer);
288 }
289
290 static void
291 _pygi_marshal_cleanup_to_py_interface_object (PyGIInvokeState *state,
292                                               PyGIArgCache    *arg_cache,
293                                               PyObject        *dummy,
294                                               gpointer         data,
295                                               gboolean         was_processed)
296 {
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));
301 }
302
303 static gboolean
304 pygi_arg_gobject_setup_from_info (PyGIArgCache      *arg_cache,
305                                   GITypeInfo        *type_info,
306                                   GIArgInfo         *arg_info,
307                                   GITransfer         transfer,
308                                   PyGIDirection      direction,
309                                   PyGICallableCache *callable_cache)
310 {
311     /* NOTE: usage of pygi_arg_interface_new_from_info already calls
312      * pygi_arg_interface_setup so no need to do it here.
313      */
314
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;
318         } else {
319             arg_cache->from_py_marshaller = _pygi_marshal_from_py_called_from_py_interface_object;
320         }
321
322         arg_cache->from_py_cleanup = _pygi_marshal_cleanup_from_py_interface_object;
323     }
324
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;
328         } else {
329             arg_cache->to_py_marshaller = _pygi_marshal_to_py_called_from_py_interface_object_cache_adapter;
330         }
331
332         arg_cache->to_py_cleanup = _pygi_marshal_cleanup_to_py_interface_object;
333     }
334
335     return TRUE;
336 }
337
338 PyGIArgCache *
339 pygi_arg_gobject_new_from_info (GITypeInfo        *type_info,
340                                 GIArgInfo         *arg_info,
341                                 GITransfer         transfer,
342                                 PyGIDirection      direction,
343                                 GIInterfaceInfo   *iface_info,
344                                 PyGICallableCache *callable_cache)
345 {
346     gboolean res = FALSE;
347     PyGIArgCache *cache = NULL;
348
349     cache = pygi_arg_interface_new_from_info (type_info,
350                                               arg_info,
351                                               transfer,
352                                               direction,
353                                               iface_info);
354     if (cache == NULL)
355         return NULL;
356
357     res = pygi_arg_gobject_setup_from_info (cache,
358                                             type_info,
359                                             arg_info,
360                                             transfer,
361                                             direction,
362                                             callable_cache);
363     if (res) {
364         return cache;
365     } else {
366         pygi_arg_cache_free (cache);
367         return NULL;
368     }
369 }