[pygobject] Handle GI_TRANSFER_EVERYTHING for returns of foreign structures



commit bbfcebdfdc5e574999221b60520422ea6da82435
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Wed Mar 12 18:32:47 2014 -0400

    Handle GI_TRANSFER_EVERYTHING for returns of foreign structures
    
    Any (transfer full) return of a cairo type other than a path
    was leaked.
    
    Pass the transfer type PyGIArgOverrideFromGIArgumentFunc and handle
    it for the cairo foreign type. For paths we can only handle
    (transfer full) so throw an error for (transfer none).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=726206

 gi/pygi-foreign-cairo.c  |   32 +++++++++++++++++++++++++-------
 gi/pygi-foreign.c        |    3 ++-
 gi/pygi-foreign.h        |    1 +
 gi/pygi-invoke.c         |    1 +
 gi/pygi-struct-marshal.c |    1 +
 gi/pygi.h                |    1 +
 6 files changed, 31 insertions(+), 8 deletions(-)
---
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c
index 3fe6a39..8261a07 100644
--- a/gi/pygi-foreign-cairo.c
+++ b/gi/pygi-foreign-cairo.c
@@ -56,11 +56,14 @@ cairo_context_to_arg (PyObject        *value,
 }
 
 static PyObject *
-cairo_context_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_context_from_arg (GIInterfaceInfo *interface_info,
+                        GITransfer       transfer,
+                        gpointer         data)
 {
     cairo_t *context = (cairo_t*) data;
 
-    cairo_reference (context);
+    if (transfer == GI_TRANSFER_NOTHING)
+        cairo_reference (context);
 
     return PycairoContext_FromContext (context, &PycairoContext_Type, NULL);
 }
@@ -95,11 +98,14 @@ cairo_surface_to_arg (PyObject        *value,
 }
 
 static PyObject *
-cairo_surface_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_surface_from_arg (GIInterfaceInfo *interface_info,
+                        GITransfer       transfer,
+                        gpointer         data)
 {
     cairo_surface_t *surface = (cairo_surface_t*) data;
 
-    cairo_surface_reference (surface);
+    if (transfer == GI_TRANSFER_NOTHING)
+        cairo_surface_reference (surface);
 
     return PycairoSurface_FromSurface (surface, NULL);
 }
@@ -134,10 +140,17 @@ cairo_path_to_arg (PyObject        *value,
 }
 
 static PyObject *
-cairo_path_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_path_from_arg (GIInterfaceInfo *interface_info,
+                     GITransfer       transfer,
+                     gpointer         data)
 {
     cairo_path_t *path = (cairo_path_t*) data;
 
+    if (transfer == GI_TRANSFER_NOTHING) {
+        PyErr_SetString(PyExc_TypeError, "Unsupported annotation (transfer none) for cairo.Path return");
+        return NULL;
+    }
+
     return PycairoPath_FromPath (path);
 }
 
@@ -170,11 +183,16 @@ cairo_font_options_to_arg (PyObject        *value,
 }
 
 static PyObject *
-cairo_font_options_from_arg (GIInterfaceInfo *interface_info, gpointer data)
+cairo_font_options_from_arg (GIInterfaceInfo *interface_info,
+                             GITransfer       transfer,
+                             gpointer         data)
 {
     cairo_font_options_t *font_options = (cairo_font_options_t*) data;
 
-    return PycairoFontOptions_FromFontOptions (cairo_font_options_copy (font_options));
+    if (transfer == GI_TRANSFER_NOTHING)
+        font_options = cairo_font_options_copy (font_options);
+
+    return PycairoFontOptions_FromFontOptions (font_options);
 }
 
 static PyObject *
diff --git a/gi/pygi-foreign.c b/gi/pygi-foreign.c
index c046d0f..f3c1a34 100644
--- a/gi/pygi-foreign.c
+++ b/gi/pygi-foreign.c
@@ -123,6 +123,7 @@ pygi_struct_foreign_convert_to_g_argument (PyObject        *value,
 
 PyObject *
 pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
+                                             GITransfer       transfer,
                                              GIArgument      *arg)
 {
     GIBaseInfo *base_info = (GIBaseInfo *) interface_info;
@@ -131,7 +132,7 @@ pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
     if (foreign_struct == NULL)
         return NULL;
 
-    return foreign_struct->from_func (interface_info, arg);
+    return foreign_struct->from_func (interface_info, transfer, arg);
 }
 
 PyObject *
diff --git a/gi/pygi-foreign.h b/gi/pygi-foreign.h
index dd5f896..478d759 100644
--- a/gi/pygi-foreign.h
+++ b/gi/pygi-foreign.h
@@ -35,6 +35,7 @@ PyObject *pygi_struct_foreign_convert_to_g_argument (PyObject           *value,
                                                      GITransfer          transfer,
                                                      GIArgument         *arg);
 PyObject *pygi_struct_foreign_convert_from_g_argument (GIInterfaceInfo *interface_info,
+                                                       GITransfer       transfer,
                                                        GIArgument      *arg);
 PyObject *pygi_struct_foreign_release (GITypeInfo *type_info,
                                        gpointer struct_);
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 3bb4dc6..f4abb26 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -401,6 +401,7 @@ _caller_alloc (PyGIArgCache *arg_cache, GIArgument *arg)
             PyObject *foreign_struct =
                 pygi_struct_foreign_convert_from_g_argument (
                     iface_cache->interface_info,
+                    GI_TRANSFER_NOTHING,
                     NULL);
 
                 pygi_struct_foreign_convert_to_g_argument (foreign_struct,
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 338f2be..7346eae 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -352,6 +352,7 @@ _pygi_marshal_to_py_interface_struct (GIArgument *arg,
         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,
+                                                              transfer,
                                                               arg->v_pointer);
     } else if (g_type_is_a (g_type, G_TYPE_BOXED)) {
         if (py_type) {
diff --git a/gi/pygi.h b/gi/pygi.h
index 3a1591f..ecd3359 100644
--- a/gi/pygi.h
+++ b/gi/pygi.h
@@ -85,6 +85,7 @@ typedef PyObject * (*PyGIArgOverrideToGIArgumentFunc) (PyObject        *value,
                                                        GITransfer       transfer,
                                                        GIArgument      *arg);
 typedef PyObject * (*PyGIArgOverrideFromGIArgumentFunc) (GIInterfaceInfo *interface_info,
+                                                         GITransfer       transfer,
                                                          gpointer         data);
 typedef PyObject * (*PyGIArgOverrideReleaseFunc) (GITypeInfo *type_info,
                                                   gpointer  struct_);


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