[pygobject] Unify interface struct to Python GI marshaling code



commit 09610bf42be76f65d7d2afe1c691f7b4a7c64e5b
Author: Simon Feltman <sfeltman src gnome org>
Date:   Fri Mar 29 03:20:44 2013 -0700

    Unify interface struct to Python GI marshaling code
    
    Add pygi_marshal_to_py_interface_struct used for direct gi method
    call out args and vfunc in args.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=693405

 gi/pygi-argument.c      |   72 ++++++------------------------
 gi/pygi-marshal-to-py.c |  112 +++++++++++++++++++++++++++++------------------
 gi/pygi-marshal-to-py.h |    8 +++
 3 files changed, 91 insertions(+), 101 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 9540f5a..af14a4d 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1570,69 +1570,25 @@ _pygi_argument_to_object (GIArgument  *arg,
                 case GI_INFO_TYPE_STRUCT:
                 case GI_INFO_TYPE_UNION:
                 {
-                    GType type;
-
-                    if (arg->v_pointer == NULL) {
-                        object = Py_None;
-                        Py_INCREF (object);
-                        break;
-                    }
-
-                    type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
-                    if (g_type_is_a (type, G_TYPE_VALUE)) {
-                        object = pyg_value_as_pyobject (arg->v_pointer, FALSE);
-                    } else if (g_struct_info_is_foreign (info)) {
-                        object = pygi_struct_foreign_convert_from_g_argument (info, arg->v_pointer);
-                    } else if (g_type_is_a (type, G_TYPE_BOXED)) {
-                        PyObject *py_type;
-
-                        py_type = _pygi_type_get_from_g_type (type);
-                        if (py_type == NULL)
-                            break;
-
-                        object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer == 
GI_TRANSFER_EVERYTHING, 0);
-
-                        Py_DECREF (py_type);
-                    } else if (g_type_is_a (type, G_TYPE_POINTER)) {
-                        PyObject *py_type;
-
-                        py_type = _pygi_type_get_from_g_type (type);
-
-                        if (py_type == NULL || !PyType_IsSubtype ( (PyTypeObject *) type, &PyGIStruct_Type)) 
{
-                            g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
-                            object = pyg_pointer_new (type, arg->v_pointer);
-                        } else {
-                            object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer 
== GI_TRANSFER_EVERYTHING);
-                        }
-
-                        Py_XDECREF (py_type);
-                   } else if (type == G_TYPE_VARIANT) {
-                        PyObject *py_type;
-
-                        g_variant_ref_sink (arg->v_pointer);
-                        py_type = _pygi_type_import_by_gi_info (info);
-                        object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer,
-                                                    transfer == GI_TRANSFER_EVERYTHING);
-                    } else if (type == G_TYPE_NONE) {
-                        PyObject *py_type;
+                    PyObject *py_type;
+                    GType g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
 
+                    /* Special case variant and none to force loading from py module. */
+                    if (g_type == G_TYPE_VARIANT || g_type == G_TYPE_NONE) {
                         py_type = _pygi_type_import_by_gi_info (info);
-                        if (py_type == NULL) {
-                            break;
-                        }
-
-                        /* Only structs created in invoke can be safely marked
-                         * GI_TRANSFER_EVERYTHING. Trust that invoke has
-                         * filtered correctly
-                         */
-                        object = _pygi_struct_new ( (PyTypeObject *) py_type, arg->v_pointer,
-                                                    transfer == GI_TRANSFER_EVERYTHING);
-
-                        Py_DECREF (py_type);
                     } else {
-                        PyErr_Format (PyExc_NotImplementedError, "structure type '%s' is not supported yet", 
g_type_name (type));
+                        py_type = _pygi_type_get_from_g_type (g_type);
                     }
 
+                    object = pygi_marshal_to_py_interface_struct (arg,
+                                                                  info, /*interface_info*/
+                                                                  g_type,
+                                                                  py_type,
+                                                                  transfer,
+                                                                  FALSE, /*is_allocated*/
+                                                                  g_struct_info_is_foreign (info));
+
+                    Py_XDECREF (py_type);
                     break;
                 }
                 case GI_INFO_TYPE_ENUM:
diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
index 31a6add..6e16b99 100644
--- a/gi/pygi-marshal-to-py.c
+++ b/gi/pygi-marshal-to-py.c
@@ -795,51 +795,15 @@ _pygi_marshal_to_py_interface_struct (PyGIInvokeState   *state,
                                       PyGIArgCache      *arg_cache,
                                       GIArgument        *arg)
 {
-    PyObject *py_obj = NULL;
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
-    GType type = iface_cache->g_type;
-
-    if (arg->v_pointer == NULL) {
-        py_obj = Py_None;
-        Py_INCREF (py_obj);
-        return py_obj;
-    }
-
-    if (g_type_is_a (type, G_TYPE_VALUE)) {
-        py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
-    } else if (iface_cache->is_foreign) {
-        py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info,
-                                                              arg->v_pointer);
-    } else if (g_type_is_a (type, G_TYPE_BOXED)) {
-        py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
-                                  arg_cache->transfer == GI_TRANSFER_EVERYTHING || 
arg_cache->is_caller_allocates,
-                                  arg_cache->is_caller_allocates ?
-                                          g_struct_info_get_size(iface_cache->interface_info) : 0);
-    } else if (g_type_is_a (type, G_TYPE_POINTER)) {
-        if (iface_cache->py_type == NULL ||
-                !PyType_IsSubtype ( (PyTypeObject *)iface_cache->py_type, &PyGIStruct_Type)) {
-            g_warn_if_fail(arg_cache->transfer == GI_TRANSFER_NOTHING);
-            py_obj = pyg_pointer_new (type, arg->v_pointer);
-        } else {
-            py_obj = _pygi_struct_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer, 
-                                       arg_cache->transfer == GI_TRANSFER_EVERYTHING);
-        }
-    } else if (g_type_is_a (type, G_TYPE_VARIANT)) {
-         g_variant_ref_sink (arg->v_pointer);
-         py_obj = _pygi_struct_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer, 
-                                    FALSE);
-    } else if (type == G_TYPE_NONE && iface_cache->is_foreign) {
-        py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info, arg->v_pointer);
-    } else if (type == G_TYPE_NONE) {
-        py_obj = _pygi_struct_new ( (PyTypeObject *) iface_cache->py_type, arg->v_pointer, 
-                                   arg_cache->transfer == GI_TRANSFER_EVERYTHING);
-    } else {
-        PyErr_Format (PyExc_NotImplementedError,
-                      "structure type '%s' is not supported yet",
-                      g_type_name (type));
-    }
 
-    return py_obj;
+    return pygi_marshal_to_py_interface_struct (arg,
+                                                iface_cache->interface_info,
+                                                iface_cache->g_type,
+                                                iface_cache->py_type,
+                                                arg_cache->transfer,
+                                                arg_cache->is_caller_allocates,
+                                                iface_cache->is_foreign);
 }
 
 PyObject *
@@ -911,3 +875,65 @@ pygi_marshal_to_py_object (GIArgument *arg, GITransfer transfer) {
 
     return pyobj;
 }
+
+PyObject *
+pygi_marshal_to_py_interface_struct (GIArgument *arg,
+                                     GIInterfaceInfo *interface_info,
+                                     GType g_type,
+                                     PyObject *py_type,
+                                     GITransfer transfer,
+                                     gboolean is_allocated,
+                                     gboolean is_foreign)
+{
+    PyObject *py_obj = NULL;
+
+    if (arg->v_pointer == NULL) {
+        Py_RETURN_NONE;
+    }
+
+    if (g_type_is_a (g_type, G_TYPE_VALUE)) {
+        py_obj = pyg_value_as_pyobject (arg->v_pointer, FALSE);
+    } else if (is_foreign) {
+        py_obj = pygi_struct_foreign_convert_from_g_argument (interface_info,
+                                                              arg->v_pointer);
+    } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
+        if (py_type) {
+            py_obj = _pygi_boxed_new ((PyTypeObject *) py_type,
+                                      arg->v_pointer,
+                                      transfer == GI_TRANSFER_EVERYTHING || is_allocated,
+                                      is_allocated ?
+                                              g_struct_info_get_size(interface_info) : 0);
+        }
+    } else if (g_type_is_a (g_type, G_TYPE_POINTER)) {
+        if (py_type == NULL ||
+                !PyType_IsSubtype ((PyTypeObject *) py_type, &PyGIStruct_Type)) {
+            g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
+            py_obj = pyg_pointer_new (g_type, arg->v_pointer);
+        } else {
+            py_obj = _pygi_struct_new ( (PyTypeObject *) py_type,
+                                       arg->v_pointer,
+                                       transfer == GI_TRANSFER_EVERYTHING);
+        }
+    } else if (g_type_is_a (g_type, G_TYPE_VARIANT)) {
+        /* Note we do not use transfer for the structs free_on_dealloc because
+         * GLib.Variant overrides __del__ to call "g_variant_unref". */
+        if (py_type) {
+            g_variant_ref_sink (arg->v_pointer);
+            py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
+                                       arg->v_pointer,
+                                       FALSE);
+        }
+    } else if (g_type == G_TYPE_NONE) {
+        if (py_type) {
+            py_obj = _pygi_struct_new ((PyTypeObject *) py_type,
+                                       arg->v_pointer,
+                                       transfer == GI_TRANSFER_EVERYTHING);
+        }
+    } else {
+        PyErr_Format (PyExc_NotImplementedError,
+                      "structure type '%s' is not supported yet",
+                      g_type_name (g_type));
+    }
+
+    return py_obj;
+}
diff --git a/gi/pygi-marshal-to-py.h b/gi/pygi-marshal-to-py.h
index f2e1a5c..359644d 100644
--- a/gi/pygi-marshal-to-py.h
+++ b/gi/pygi-marshal-to-py.h
@@ -144,6 +144,14 @@ PyObject *_pygi_marshal_to_py_interface_union  (PyGIInvokeState   *state,
 PyObject *pygi_marshal_to_py_object (GIArgument *arg,
                                      GITransfer transfer);
 
+PyObject *pygi_marshal_to_py_interface_struct (GIArgument *arg,
+                                               GIInterfaceInfo *interface_info,
+                                               GType g_type,
+                                               PyObject *py_type,
+                                               GITransfer transfer,
+                                               gboolean is_allocated,
+                                               gboolean is_foreign);
+
 G_END_DECLS
 
 #endif /* __PYGI_MARSHAL_TO_PY_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]