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/>.
24 #include "pygi-python-compat.h"
25 #include "pygi-struct-marshal.h"
26 #include "pygi-struct.h"
27 #include "pygi-foreign.h"
28 #include "pygi-value.h"
29 #include "pygi-type.h"
30 #include "pygi-boxed.h"
31 #include "pygi-info.h"
32 #include "pygpointer.h"
34 #include "pygi-type.h"
37 * _is_union_member - check to see if the py_arg is actually a member of the
41 _is_union_member (GIInterfaceInfo
*interface_info
, PyObject
*py_arg
) {
44 GIUnionInfo
*union_info
;
46 gboolean is_member
= FALSE
;
48 info_type
= g_base_info_get_type (interface_info
);
50 if (info_type
!= GI_INFO_TYPE_UNION
)
53 union_info
= (GIUnionInfo
*) interface_info
;
54 n_fields
= g_union_info_get_n_fields (union_info
);
56 for (i
= 0; i
< n_fields
; i
++) {
57 GIFieldInfo
*field_info
;
58 GITypeInfo
*field_type_info
;
60 field_info
= g_union_info_get_field (union_info
, i
);
61 field_type_info
= g_field_info_get_type (field_info
);
63 /* we can only check if the members are interfaces */
64 if (g_type_info_get_tag (field_type_info
) == GI_TYPE_TAG_INTERFACE
) {
65 GIInterfaceInfo
*field_iface_info
;
68 field_iface_info
= g_type_info_get_interface (field_type_info
);
69 py_type
= pygi_type_import_by_gi_info ((GIBaseInfo
*) field_iface_info
);
71 if (py_type
!= NULL
&& PyObject_IsInstance (py_arg
, py_type
)) {
76 g_base_info_unref ( ( GIBaseInfo
*) field_iface_info
);
79 g_base_info_unref ( ( GIBaseInfo
*) field_type_info
);
80 g_base_info_unref ( ( GIBaseInfo
*) field_info
);
94 /* pygi_arg_gvalue_from_py_marshal:
98 * copy_reference: TRUE if arg should use the pointer reference held by py_arg
99 * when it is already holding a GValue vs. copying the value.
102 pygi_arg_gvalue_from_py_marshal (PyObject
*py_arg
,
105 gboolean copy_reference
) {
109 object_type
= pyg_type_from_object_strict ( (PyObject
*) Py_TYPE (py_arg
), FALSE
);
110 if (object_type
== G_TYPE_INVALID
) {
111 PyErr_SetString (PyExc_RuntimeError
, "unable to retrieve object's GType");
115 /* if already a gvalue, use that, else marshal into gvalue */
116 if (object_type
== G_TYPE_VALUE
) {
117 GValue
*source_value
= pyg_boxed_get (py_arg
, GValue
);
118 if (copy_reference
) {
119 value
= source_value
;
121 value
= g_slice_new0 (GValue
);
122 g_value_init (value
, G_VALUE_TYPE (source_value
));
123 g_value_copy (source_value
, value
);
126 value
= g_slice_new0 (GValue
);
127 g_value_init (value
, object_type
);
128 if (pyg_value_from_pyobject_with_error (value
, py_arg
) < 0) {
129 g_slice_free (GValue
, value
);
134 arg
->v_pointer
= value
;
139 pygi_arg_gvalue_from_py_cleanup (PyGIInvokeState
*state
,
140 PyGIArgCache
*arg_cache
,
143 gboolean was_processed
)
145 /* Note py_arg can be NULL for hash table which is a bug. */
146 if (was_processed
&& py_arg
!= NULL
) {
147 GType py_object_type
=
148 pyg_type_from_object_strict ( (PyObject
*) Py_TYPE (py_arg
), FALSE
);
150 /* When a GValue was not passed, it means the marshalers created a new
151 * one to pass in, clean this up.
153 if (py_object_type
!= G_TYPE_VALUE
) {
154 g_value_unset ((GValue
*) data
);
155 g_slice_free (GValue
, data
);
160 /* pygi_arg_gclosure_from_py_marshal:
165 pygi_arg_gclosure_from_py_marshal (PyObject
*py_arg
,
170 GType object_gtype
= pyg_type_from_object_strict (py_arg
, FALSE
);
172 if ( !(PyCallable_Check(py_arg
) ||
173 g_type_is_a (object_gtype
, G_TYPE_CLOSURE
))) {
174 PyErr_Format (PyExc_TypeError
, "Must be callable, not %s",
175 Py_TYPE (py_arg
)->tp_name
);
179 if (g_type_is_a (object_gtype
, G_TYPE_CLOSURE
)) {
180 closure
= (GClosure
*)pyg_boxed_get (py_arg
, void);
181 /* Make sure we own a ref which is held until cleanup. */
182 if (closure
!= NULL
) {
183 g_closure_ref (closure
);
186 closure
= pyg_closure_new (py_arg
, NULL
, NULL
);
187 g_closure_ref (closure
);
188 g_closure_sink (closure
);
191 if (closure
== NULL
) {
192 PyErr_SetString (PyExc_RuntimeError
, "PyObject conversion to GClosure failed");
196 /* Add an additional ref when transfering everything to the callee. */
197 if (transfer
== GI_TRANSFER_EVERYTHING
) {
198 g_closure_ref (closure
);
201 arg
->v_pointer
= closure
;
206 arg_gclosure_from_py_cleanup (PyGIInvokeState
*state
,
207 PyGIArgCache
*arg_cache
,
209 gpointer cleanup_data
,
210 gboolean was_processed
)
212 if (cleanup_data
!= NULL
) {
213 g_closure_unref (cleanup_data
);
217 /* pygi_arg_struct_from_py_marshal:
219 * Dispatcher to various sub marshalers
222 pygi_arg_struct_from_py_marshal (PyObject
*py_arg
,
224 const gchar
*arg_name
,
225 GIBaseInfo
*interface_info
,
229 gboolean copy_reference
,
233 gboolean is_union
= FALSE
;
235 if (py_arg
== Py_None
) {
236 arg
->v_pointer
= NULL
;
240 /* FIXME: handle this large if statement in the cache
241 * and set the correct marshaller
244 if (g_type_is_a (g_type
, G_TYPE_CLOSURE
)) {
245 return pygi_arg_gclosure_from_py_marshal (py_arg
, arg
, transfer
);
246 } else if (g_type_is_a (g_type
, G_TYPE_VALUE
)) {
247 return pygi_arg_gvalue_from_py_marshal(py_arg
,
251 } else if (is_foreign
) {
253 success
= pygi_struct_foreign_convert_to_g_argument (py_arg
,
258 return (success
== Py_None
);
259 } else if (!PyObject_IsInstance (py_arg
, py_type
)) {
260 /* first check to see if this is a member of the expected union */
261 is_union
= _is_union_member (interface_info
, py_arg
);
267 if (g_type_is_a (g_type
, G_TYPE_BOXED
)) {
268 /* Additionally use pyg_type_from_object to pull the stashed __gtype__
269 * attribute off of the input argument for type checking. This is needed
270 * to work around type discrepancies in cases with aliased (typedef) types.
271 * e.g. GtkAllocation, GdkRectangle.
272 * See: https://bugzilla.gnomethere are .org/show_bug.cgi?id=707140
274 if (is_union
|| pyg_boxed_check (py_arg
, g_type
) ||
275 g_type_is_a (pyg_type_from_object (py_arg
), g_type
)) {
276 arg
->v_pointer
= pyg_boxed_get (py_arg
, void);
277 if (transfer
== GI_TRANSFER_EVERYTHING
) {
278 arg
->v_pointer
= g_boxed_copy (g_type
, arg
->v_pointer
);
284 } else if (g_type_is_a (g_type
, G_TYPE_POINTER
) ||
285 g_type_is_a (g_type
, G_TYPE_VARIANT
) ||
286 g_type
== G_TYPE_NONE
) {
287 g_warn_if_fail (g_type_is_a (g_type
, G_TYPE_VARIANT
) || !is_pointer
|| transfer
== GI_TRANSFER_NOTHING
);
289 if (g_type_is_a (g_type
, G_TYPE_VARIANT
) &&
290 pyg_type_from_object (py_arg
) != G_TYPE_VARIANT
) {
291 PyErr_SetString (PyExc_TypeError
, "expected GLib.Variant");
294 arg
->v_pointer
= pyg_pointer_get (py_arg
, void);
295 if (transfer
== GI_TRANSFER_EVERYTHING
) {
296 g_variant_ref ((GVariant
*)arg
->v_pointer
);
300 PyErr_Format (PyExc_NotImplementedError
,
301 "structure type '%s' is not supported yet",
302 g_type_name(g_type
));
309 gchar
*type_name
= _pygi_g_base_info_get_fullname (interface_info
);
310 PyObject
*module
= PyObject_GetAttrString(py_arg
, "__module__");
312 PyErr_Format (PyExc_TypeError
, "argument %s: Expected %s, but got %s%s%s",
313 arg_name
? arg_name
: "self",
315 module
? PYGLIB_PyUnicode_AsString(module
) : "",
317 Py_TYPE (py_arg
)->tp_name
);
326 arg_struct_from_py_marshal_adapter (PyGIInvokeState
*state
,
327 PyGICallableCache
*callable_cache
,
328 PyGIArgCache
*arg_cache
,
331 gpointer
*cleanup_data
)
333 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
335 gboolean res
= pygi_arg_struct_from_py_marshal (py_arg
,
338 iface_cache
->interface_info
,
340 iface_cache
->py_type
,
342 TRUE
, /*copy_reference*/
343 iface_cache
->is_foreign
,
344 arg_cache
->is_pointer
);
346 /* Assume struct marshaling is always a pointer and assign cleanup_data
347 * here rather than passing it further down the chain.
349 *cleanup_data
= arg
->v_pointer
;
354 arg_foreign_from_py_cleanup (PyGIInvokeState
*state
,
355 PyGIArgCache
*arg_cache
,
358 gboolean was_processed
)
360 if (state
->failed
&& was_processed
) {
361 pygi_struct_foreign_release (
362 ( (PyGIInterfaceCache
*)arg_cache
)->interface_info
,
368 pygi_arg_struct_to_py_marshaller (GIArgument
*arg
,
369 GIInterfaceInfo
*interface_info
,
373 gboolean is_allocated
,
376 PyObject
*py_obj
= NULL
;
378 if (arg
->v_pointer
== NULL
) {
382 if (g_type_is_a (g_type
, G_TYPE_VALUE
)) {
383 py_obj
= pyg_value_as_pyobject (arg
->v_pointer
, FALSE
);
384 } else if (is_foreign
) {
385 py_obj
= pygi_struct_foreign_convert_from_g_argument (interface_info
,
388 } else if (g_type_is_a (g_type
, G_TYPE_BOXED
)) {
390 py_obj
= pygi_boxed_new ((PyTypeObject
*) py_type
,
392 transfer
== GI_TRANSFER_EVERYTHING
|| is_allocated
,
394 g_struct_info_get_size(interface_info
) : 0);
396 } else if (g_type_is_a (g_type
, G_TYPE_POINTER
)) {
397 if (py_type
== NULL
||
398 !PyType_IsSubtype ((PyTypeObject
*) py_type
, &PyGIStruct_Type
)) {
399 g_warn_if_fail (transfer
== GI_TRANSFER_NOTHING
);
400 py_obj
= pyg_pointer_new (g_type
, arg
->v_pointer
);
402 py_obj
= pygi_struct_new ( (PyTypeObject
*) py_type
,
404 transfer
== GI_TRANSFER_EVERYTHING
);
406 } else if (g_type_is_a (g_type
, G_TYPE_VARIANT
)) {
407 /* Note: sink the variant (add a ref) only if we are not transfered ownership.
408 * GLib.Variant overrides __del__ which will then call "g_variant_unref" for
409 * cleanup in either case. */
411 if (transfer
== GI_TRANSFER_NOTHING
) {
412 g_variant_ref_sink (arg
->v_pointer
);
414 py_obj
= pygi_struct_new ((PyTypeObject
*) py_type
,
418 } else if (g_type
== G_TYPE_NONE
) {
420 py_obj
= pygi_struct_new ((PyTypeObject
*) py_type
,
422 transfer
== GI_TRANSFER_EVERYTHING
|| is_allocated
);
425 PyErr_Format (PyExc_NotImplementedError
,
426 "structure type '%s' is not supported yet",
427 g_type_name (g_type
));
434 pygi_arg_struct_to_py_marshal (GIArgument
*arg
,
435 GIInterfaceInfo
*interface_info
,
439 gboolean is_allocated
,
442 PyObject
*ret
= pygi_arg_struct_to_py_marshaller (arg
, interface_info
, g_type
, py_type
, transfer
, is_allocated
, is_foreign
);
444 if (ret
&& PyObject_IsInstance (ret
, (PyObject
*) &PyGIBoxed_Type
) && transfer
== GI_TRANSFER_NOTHING
)
445 pygi_boxed_copy_in_place ((PyGIBoxed
*) ret
);
451 arg_struct_to_py_marshal_adapter (PyGIInvokeState
*state
,
452 PyGICallableCache
*callable_cache
,
453 PyGIArgCache
*arg_cache
,
455 gpointer
*cleanup_data
)
457 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
460 ret
= pygi_arg_struct_to_py_marshaller (arg
,
461 iface_cache
->interface_info
,
463 iface_cache
->py_type
,
465 arg_cache
->is_caller_allocates
,
466 iface_cache
->is_foreign
);
474 arg_foreign_to_py_cleanup (PyGIInvokeState
*state
,
475 PyGIArgCache
*arg_cache
,
476 gpointer cleanup_data
,
478 gboolean was_processed
)
480 if (!was_processed
&& arg_cache
->transfer
== GI_TRANSFER_EVERYTHING
) {
481 pygi_struct_foreign_release (
482 ( (PyGIInterfaceCache
*)arg_cache
)->interface_info
,
488 arg_boxed_to_py_cleanup (PyGIInvokeState
*state
,
489 PyGIArgCache
*arg_cache
,
490 gpointer cleanup_data
,
492 gboolean was_processed
)
494 if (arg_cache
->transfer
== GI_TRANSFER_NOTHING
)
495 pygi_boxed_copy_in_place ((PyGIBoxed
*) cleanup_data
);
499 arg_type_class_from_py_marshal (PyGIInvokeState
*state
,
500 PyGICallableCache
*callable_cache
,
501 PyGIArgCache
*arg_cache
,
504 gpointer
*cleanup_data
)
506 GType gtype
= pyg_type_from_object (py_arg
);
508 if (G_TYPE_IS_CLASSED (gtype
)) {
509 arg
->v_pointer
= g_type_class_ref (gtype
);
510 *cleanup_data
= arg
->v_pointer
;
513 PyErr_Format (PyExc_TypeError
,
514 "Unable to retrieve a GObject type class from \"%s\".",
515 Py_TYPE(py_arg
)->tp_name
);
521 arg_type_class_from_py_cleanup (PyGIInvokeState
*state
,
522 PyGIArgCache
*arg_cache
,
525 gboolean was_processed
)
528 g_type_class_unref (data
);
533 arg_struct_from_py_setup (PyGIArgCache
*arg_cache
,
534 GIInterfaceInfo
*iface_info
,
537 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
539 if (g_struct_info_is_gtype_struct ((GIStructInfo
*)iface_info
)) {
540 arg_cache
->from_py_marshaller
= arg_type_class_from_py_marshal
;
541 /* Since we always add a ref in the marshalling, only unref the
542 * GTypeClass when we don't transfer ownership. */
543 if (transfer
== GI_TRANSFER_NOTHING
) {
544 arg_cache
->from_py_cleanup
= arg_type_class_from_py_cleanup
;
548 arg_cache
->from_py_marshaller
= arg_struct_from_py_marshal_adapter
;
550 if (g_type_is_a (iface_cache
->g_type
, G_TYPE_CLOSURE
)) {
551 arg_cache
->from_py_cleanup
= arg_gclosure_from_py_cleanup
;
553 } else if (iface_cache
->g_type
== G_TYPE_VALUE
) {
554 arg_cache
->from_py_cleanup
= pygi_arg_gvalue_from_py_cleanup
;
556 } else if (iface_cache
->is_foreign
) {
557 arg_cache
->from_py_cleanup
= arg_foreign_from_py_cleanup
;
563 arg_struct_to_py_setup (PyGIArgCache
*arg_cache
,
564 GIInterfaceInfo
*iface_info
,
567 PyGIInterfaceCache
*iface_cache
= (PyGIInterfaceCache
*)arg_cache
;
569 if (arg_cache
->to_py_marshaller
== NULL
) {
570 arg_cache
->to_py_marshaller
= arg_struct_to_py_marshal_adapter
;
573 iface_cache
->is_foreign
= g_struct_info_is_foreign ( (GIStructInfo
*)iface_info
);
575 if (iface_cache
->is_foreign
)
576 arg_cache
->to_py_cleanup
= arg_foreign_to_py_cleanup
;
577 else if (!g_type_is_a (iface_cache
->g_type
, G_TYPE_VALUE
) &&
578 iface_cache
->py_type
&&
579 g_type_is_a (iface_cache
->g_type
, G_TYPE_BOXED
))
580 arg_cache
->to_py_cleanup
= arg_boxed_to_py_cleanup
;
584 pygi_arg_struct_new_from_info (GITypeInfo
*type_info
,
587 PyGIDirection direction
,
588 GIInterfaceInfo
*iface_info
)
590 PyGIArgCache
*cache
= NULL
;
591 PyGIInterfaceCache
*iface_cache
;
593 cache
= pygi_arg_interface_new_from_info (type_info
,
601 iface_cache
= (PyGIInterfaceCache
*)cache
;
602 iface_cache
->is_foreign
= (g_base_info_get_type ((GIBaseInfo
*) iface_info
) == GI_INFO_TYPE_STRUCT
) &&
603 (g_struct_info_is_foreign ((GIStructInfo
*) iface_info
));
605 if (direction
& PYGI_DIRECTION_FROM_PYTHON
) {
606 arg_struct_from_py_setup (cache
, iface_info
, transfer
);
609 if (direction
& PYGI_DIRECTION_TO_PYTHON
) {
610 arg_struct_to_py_setup (cache
, iface_info
, transfer
);