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-struct-marshal.h"
26 #include "pygi-private.h"
27 #include "pygi-value.h"
30 * _is_union_member - check to see if the py_arg is actually a member of the
34 _is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
37 GIUnionInfo *union_info;
39 gboolean is_member = FALSE;
41 info_type = g_base_info_get_type (interface_info);
43 if (info_type != GI_INFO_TYPE_UNION)
46 union_info = (GIUnionInfo *) interface_info;
47 n_fields = g_union_info_get_n_fields (union_info);
49 for (i = 0; i < n_fields; i++) {
50 GIFieldInfo *field_info;
51 GITypeInfo *field_type_info;
53 field_info = g_union_info_get_field (union_info, i);
54 field_type_info = g_field_info_get_type (field_info);
56 /* we can only check if the members are interfaces */
57 if (g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) {
58 GIInterfaceInfo *field_iface_info;
61 field_iface_info = g_type_info_get_interface (field_type_info);
62 py_type = _pygi_type_import_by_gi_info ((GIBaseInfo *) field_iface_info);
64 if (py_type != NULL && PyObject_IsInstance (py_arg, py_type)) {
69 g_base_info_unref ( ( GIBaseInfo *) field_iface_info);
72 g_base_info_unref ( ( GIBaseInfo *) field_type_info);
73 g_base_info_unref ( ( GIBaseInfo *) field_info);
87 /* pygi_arg_gvalue_from_py_marshal:
91 * copy_reference: TRUE if arg should use the pointer reference held by py_arg
92 * when it is already holding a GValue vs. copying the value.
95 pygi_arg_gvalue_from_py_marshal (PyObject *py_arg,
98 gboolean copy_reference) {
102 object_type = pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
103 if (object_type == G_TYPE_INVALID) {
104 PyErr_SetString (PyExc_RuntimeError, "unable to retrieve object's GType");
108 /* if already a gvalue, use that, else marshal into gvalue */
109 if (object_type == G_TYPE_VALUE) {
110 GValue *source_value = pyg_boxed_get (py_arg, GValue);
111 if (copy_reference) {
112 value = source_value;
114 value = g_slice_new0 (GValue);
115 g_value_init (value, G_VALUE_TYPE (source_value));
116 g_value_copy (source_value, value);
119 value = g_slice_new0 (GValue);
120 g_value_init (value, object_type);
121 if (pyg_value_from_pyobject (value, py_arg) < 0) {
122 g_slice_free (GValue, value);
123 PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GValue failed");
128 arg->v_pointer = value;
133 pygi_arg_gvalue_from_py_cleanup (PyGIInvokeState *state,
134 PyGIArgCache *arg_cache,
137 gboolean was_processed)
139 /* Note py_arg can be NULL for hash table which is a bug. */
140 if (was_processed && py_arg != NULL) {
141 GType py_object_type =
142 pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
144 /* When a GValue was not passed, it means the marshalers created a new
145 * one to pass in, clean this up.
147 if (py_object_type != G_TYPE_VALUE) {
148 g_value_unset ((GValue *) data);
149 g_slice_free (GValue, data);
154 /* pygi_arg_gclosure_from_py_marshal:
159 pygi_arg_gclosure_from_py_marshal (PyObject *py_arg,
164 GType object_gtype = pyg_type_from_object_strict (py_arg, FALSE);
166 if ( !(PyCallable_Check(py_arg) ||
167 g_type_is_a (object_gtype, G_TYPE_CLOSURE))) {
168 PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
169 py_arg->ob_type->tp_name);
173 if (g_type_is_a (object_gtype, G_TYPE_CLOSURE)) {
174 closure = (GClosure *)pyg_boxed_get (py_arg, void);
175 /* Make sure we own a ref which is held until cleanup. */
176 if (closure != NULL) {
177 g_closure_ref (closure);
180 closure = pyg_closure_new (py_arg, NULL, NULL);
181 g_closure_ref (closure);
182 g_closure_sink (closure);
185 if (closure == NULL) {
186 PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
190 /* Add an additional ref when transfering everything to the callee. */
191 if (transfer == GI_TRANSFER_EVERYTHING) {
192 g_closure_ref (closure);
195 arg->v_pointer = closure;
200 arg_gclosure_from_py_cleanup (PyGIInvokeState *state,
201 PyGIArgCache *arg_cache,
203 gpointer cleanup_data,
204 gboolean was_processed)
206 if (cleanup_data != NULL) {
207 g_closure_unref (cleanup_data);
211 /* pygi_arg_struct_from_py_marshal:
213 * Dispatcher to various sub marshalers
216 pygi_arg_struct_from_py_marshal (PyObject *py_arg,
218 const gchar *arg_name,
219 GIBaseInfo *interface_info,
223 gboolean copy_reference,
227 gboolean is_union = FALSE;
229 if (py_arg == Py_None) {
230 arg->v_pointer = NULL;
234 /* FIXME: handle this large if statement in the cache
235 * and set the correct marshaller
238 if (g_type_is_a (g_type, G_TYPE_CLOSURE)) {
239 return pygi_arg_gclosure_from_py_marshal (py_arg, arg, transfer);
240 } else if (g_type_is_a (g_type, G_TYPE_VALUE)) {
241 return pygi_arg_gvalue_from_py_marshal(py_arg,
245 } else if (is_foreign) {
247 success = pygi_struct_foreign_convert_to_g_argument (py_arg,
252 return (success == Py_None);
253 } else if (!PyObject_IsInstance (py_arg, py_type)) {
254 /* first check to see if this is a member of the expected union */
255 is_union = _is_union_member (interface_info, py_arg);
261 if (g_type_is_a (g_type, G_TYPE_BOXED)) {
262 /* Additionally use pyg_type_from_object to pull the stashed __gtype__
263 * attribute off of the input argument for type checking. This is needed
264 * to work around type discrepancies in cases with aliased (typedef) types.
265 * e.g. GtkAllocation, GdkRectangle.
266 * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140
268 if (is_union || pyg_boxed_check (py_arg, g_type) ||
269 g_type_is_a (pyg_type_from_object (py_arg), g_type)) {
270 arg->v_pointer = pyg_boxed_get (py_arg, void);
271 if (transfer == GI_TRANSFER_EVERYTHING) {
272 arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer);
278 } else if (g_type_is_a (g_type, G_TYPE_POINTER) ||
279 g_type_is_a (g_type, G_TYPE_VARIANT) ||
280 g_type == G_TYPE_NONE) {
281 g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !is_pointer || transfer == GI_TRANSFER_NOTHING);
283 if (g_type_is_a (g_type, G_TYPE_VARIANT) &&
284 pyg_type_from_object (py_arg) != G_TYPE_VARIANT) {
285 PyErr_SetString (PyExc_TypeError, "expected GLib.Variant");
288 arg->v_pointer = pyg_pointer_get (py_arg, void);
289 if (transfer == GI_TRANSFER_EVERYTHING) {
290 g_variant_ref ((GVariant *)arg->v_pointer);
294 PyErr_Format (PyExc_NotImplementedError,
295 "structure type '%s' is not supported yet",
296 g_type_name(g_type));
303 gchar *type_name = _pygi_g_base_info_get_fullname (interface_info);
304 PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
306 PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
307 arg_name ? arg_name : "self",
309 module ? PYGLIB_PyUnicode_AsString(module) : "",
311 py_arg->ob_type->tp_name);
320 arg_struct_from_py_marshal_adapter (PyGIInvokeState *state,
321 PyGICallableCache *callable_cache,
322 PyGIArgCache *arg_cache,
325 gpointer *cleanup_data)
327 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
329 gboolean res = pygi_arg_struct_from_py_marshal (py_arg,
332 iface_cache->interface_info,
334 iface_cache->py_type,
336 TRUE, /*copy_reference*/
337 iface_cache->is_foreign,
338 arg_cache->is_pointer);
340 /* Assume struct marshaling is always a pointer and assign cleanup_data
341 * here rather than passing it further down the chain.
343 *cleanup_data = arg->v_pointer;
348 arg_foreign_from_py_cleanup (PyGIInvokeState *state,
349 PyGIArgCache *arg_cache,
352 gboolean was_processed)
354 if (state->failed && was_processed) {
355 pygi_struct_foreign_release (
356 ( (PyGIInterfaceCache *)arg_cache)->interface_info,
363 pygi_arg_struct_to_py_marshal (GIArgument *arg,
364 GIInterfaceInfo *interface_info,
368 gboolean is_allocated,
371 PyObject *py_obj = NULL;
373 if (arg->v_pointer == NULL) {
377 if (g_type_is_a (g_type, G_TYPE_VALUE)) {
378 py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
379 } else if (is_foreign) {
380 py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
383 } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
385 /* Force a boxed copy if we are not transfered ownership and the
386 * memory is not caller allocated. */
387 py_obj = _pygi_boxed_new ((PyTypeObject *) py_type,
389 transfer == GI_TRANSFER_NOTHING && !is_allocated,
391 g_struct_info_get_size(interface_info) : 0);
393 } else if (g_type_is_a (g_type, G_TYPE_POINTER)) {
394 if (py_type == NULL ||
395 !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) {
396 g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
397 py_obj = pyg_pointer_new (g_type, arg->v_pointer);
399 py_obj = _pygi_struct_new ( (PyTypeObject *) py_type,
401 transfer == GI_TRANSFER_EVERYTHING);
403 } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) {
404 /* Note: sink the variant (add a ref) only if we are not transfered ownership.
405 * GLib.Variant overrides __del__ which will then call "g_variant_unref" for
406 * cleanup in either case. */
408 if (transfer == GI_TRANSFER_NOTHING) {
409 g_variant_ref_sink (arg->v_pointer);
411 py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
415 } else if (g_type == G_TYPE_NONE) {
417 py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
419 transfer == GI_TRANSFER_EVERYTHING || is_allocated);
422 PyErr_Format (PyExc_NotImplementedError,
423 "structure type '%s' is not supported yet",
424 g_type_name (g_type));
431 arg_struct_to_py_marshal_adapter (PyGIInvokeState *state,
432 PyGICallableCache *callable_cache,
433 PyGIArgCache *arg_cache,
436 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
438 return pygi_arg_struct_to_py_marshal (arg,
439 iface_cache->interface_info,
441 iface_cache->py_type,
443 arg_cache->is_caller_allocates,
444 iface_cache->is_foreign);
448 arg_boxed_to_py_marshal_pass_by_ref (PyGIInvokeState *state,
449 PyGICallableCache *callable_cache,
450 PyGIArgCache *arg_cache,
453 PyObject *py_obj = NULL;
454 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
456 if (arg->v_pointer == NULL) {
460 if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
461 if (iface_cache->py_type) {
462 py_obj = _pygi_boxed_new ((PyTypeObject *) iface_cache->py_type,
464 FALSE, /* copy_boxed */
465 0); /* slice_alloc */
466 ((PyGBoxed *)py_obj)->free_on_dealloc = FALSE;
469 PyErr_Format (PyExc_NotImplementedError,
470 "expected boxed type but got %s",
471 g_type_name (iface_cache->g_type));
478 arg_foreign_to_py_cleanup (PyGIInvokeState *state,
479 PyGIArgCache *arg_cache,
482 gboolean was_processed)
484 if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
485 pygi_struct_foreign_release (
486 ( (PyGIInterfaceCache *)arg_cache)->interface_info,
492 arg_type_class_from_py_marshal (PyGIInvokeState *state,
493 PyGICallableCache *callable_cache,
494 PyGIArgCache *arg_cache,
497 gpointer *cleanup_data)
499 GType gtype = pyg_type_from_object (py_arg);
501 if (G_TYPE_IS_CLASSED (gtype)) {
502 arg->v_pointer = g_type_class_ref (gtype);
503 *cleanup_data = arg->v_pointer;
506 PyErr_Format (PyExc_TypeError,
507 "Unable to retrieve a GObject type class from \"%s\".",
508 Py_TYPE(py_arg)->tp_name);
514 arg_type_class_from_py_cleanup (PyGIInvokeState *state,
515 PyGIArgCache *arg_cache,
518 gboolean was_processed)
521 g_type_class_unref (data);
526 arg_struct_from_py_setup (PyGIArgCache *arg_cache,
527 GIInterfaceInfo *iface_info,
530 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
532 if (g_struct_info_is_gtype_struct ((GIStructInfo*)iface_info)) {
533 arg_cache->from_py_marshaller = arg_type_class_from_py_marshal;
534 /* Since we always add a ref in the marshalling, only unref the
535 * GTypeClass when we don't transfer ownership. */
536 if (transfer == GI_TRANSFER_NOTHING) {
537 arg_cache->from_py_cleanup = arg_type_class_from_py_cleanup;
541 arg_cache->from_py_marshaller = arg_struct_from_py_marshal_adapter;
543 if (g_type_is_a (iface_cache->g_type, G_TYPE_CLOSURE)) {
544 arg_cache->from_py_cleanup = arg_gclosure_from_py_cleanup;
546 } else if (iface_cache->g_type == G_TYPE_VALUE) {
547 arg_cache->from_py_cleanup = pygi_arg_gvalue_from_py_cleanup;
549 } else if (iface_cache->is_foreign) {
550 arg_cache->from_py_cleanup = arg_foreign_from_py_cleanup;
556 arg_struct_to_py_setup (PyGIArgCache *arg_cache,
557 GIInterfaceInfo *iface_info,
561 PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
563 /* HACK to force GtkTreeModel:iter_next() and iter_previous() vfunc implementations
564 * to receive their Gtk.TreeIter argument as pass-by-reference. We create a new
565 * PyGIBoxed wrapper which does not copy the memory and also does not free it.
566 * This is needed to hack the noted vfunc implementations so they can continue
567 * working with bug https://bugzilla.gnome.org/show_bug.cgi?id=722899
568 * being fixed. This hack should be removed once GTK+ has fixed bug
569 * https://bugzilla.gnome.org/show_bug.cgi?id=734465
570 * and we've moved to a new major version.
572 if (arg_info && g_strcmp0 (iface_cache->type_name, "Gtk.TreeIter") == 0) {
575 GIBaseInfo *info = g_base_info_get_container (arg_info);
576 if (info && g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK &&
577 (g_strcmp0 (g_base_info_get_name (info), "iter_next") == 0 ||
578 g_strcmp0 (g_base_info_get_name (info), "iter_previous") == 0)) {
581 info = g_base_info_get_container (info);
582 if (info && g_base_info_get_type (info) == GI_INFO_TYPE_TYPE &&
583 g_type_info_get_tag ((GITypeInfo *)info) == GI_TYPE_TAG_INTERFACE) {
586 info = g_base_info_get_container (info);
587 if (info && g_base_info_get_type (info) == GI_INFO_TYPE_FIELD) {
590 info = g_base_info_get_container (info);
591 if (info && g_base_info_get_type (info) == GI_INFO_TYPE_STRUCT &&
592 g_strcmp0 (g_base_info_get_name (info), "TreeModelIface") == 0) {
593 arg_cache->to_py_marshaller = arg_boxed_to_py_marshal_pass_by_ref;
600 if (arg_cache->to_py_marshaller == NULL) {
601 arg_cache->to_py_marshaller = arg_struct_to_py_marshal_adapter;
604 if (iface_cache->is_foreign)
605 arg_cache->to_py_cleanup = arg_foreign_to_py_cleanup;
609 pygi_arg_struct_new_from_info (GITypeInfo *type_info,
612 PyGIDirection direction,
613 GIInterfaceInfo *iface_info)
615 PyGIArgCache *cache = NULL;
616 PyGIInterfaceCache *iface_cache;
618 cache = pygi_arg_interface_new_from_info (type_info,
626 iface_cache = (PyGIInterfaceCache *)cache;
627 iface_cache->is_foreign = (g_base_info_get_type ((GIBaseInfo *) iface_info) == GI_INFO_TYPE_STRUCT) &&
628 (g_struct_info_is_foreign ((GIStructInfo*) iface_info));
630 if (direction & PYGI_DIRECTION_FROM_PYTHON) {
631 arg_struct_from_py_setup (cache, iface_info, transfer);
634 if (direction & PYGI_DIRECTION_TO_PYTHON) {
635 arg_struct_to_py_setup (cache, iface_info, transfer, arg_info);