[pygobject: 4/5] to python struct marshalling: copy boxed during cleanup



commit 7ed8191818733b9130bce84f782dc6f8f734abf7
Author: Mathieu Duponchelle <mathieu centricular com>
Date:   Tue Jan 23 15:58:38 2018 +0100

    to python struct marshalling: copy boxed during cleanup
    
    If the boxed was passed with transfer nothing, we need to
    make a copy of it in the boxed wrapper, this in order
    to have a valid reference, but still let closures modify
    the original reference while it is valid (during the closure)
    
    This fixes an expected failure in the tests, that was added
    by https://bugzilla.gnome.org/show_bug.cgi?id=722899, first fixed
    by https://bugzilla.gnome.org/show_bug.cgi?id=726999 and broken
    in the preceding commits.

 gi/pygi-struct-marshal.c | 34 +++++++++++++++++++++++++++-------
 tests/test_gi.py         |  1 -
 2 files changed, 27 insertions(+), 8 deletions(-)
---
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index f1b9f13b..44797e75 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -439,14 +439,19 @@ arg_struct_to_py_marshal_adapter (PyGIInvokeState   *state,
                                   gpointer          *cleanup_data)
 {
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
+    PyObject *ret;
 
-    return pygi_arg_struct_to_py_marshal (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);
+    ret = pygi_arg_struct_to_py_marshal (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);
+
+    *cleanup_data = ret;
+
+    return ret;
 }
 
 static void
@@ -463,6 +468,17 @@ arg_foreign_to_py_cleanup (PyGIInvokeState *state,
     }
 }
 
+static void
+arg_boxed_to_py_cleanup (PyGIInvokeState *state,
+                           PyGIArgCache    *arg_cache,
+                           gpointer         cleanup_data,
+                           gpointer         data,
+                           gboolean         was_processed)
+{
+    if (arg_cache->transfer == GI_TRANSFER_NOTHING)
+        _pygi_boxed_copy_in_place ((PyGIBoxed *) cleanup_data);
+}
+
 static gboolean
 arg_type_class_from_py_marshal (PyGIInvokeState   *state,
                                 PyGICallableCache *callable_cache,
@@ -542,6 +558,10 @@ arg_struct_to_py_setup (PyGIArgCache     *arg_cache,
 
     if (iface_cache->is_foreign)
         arg_cache->to_py_cleanup = arg_foreign_to_py_cleanup;
+    else if (!g_type_is_a (iface_cache->g_type, G_TYPE_VALUE) &&
+             iface_cache->py_type &&
+             g_type_is_a (iface_cache->g_type, G_TYPE_BOXED))
+        arg_cache->to_py_cleanup = arg_boxed_to_py_cleanup;
 }
 
 PyGIArgCache *
diff --git a/tests/test_gi.py b/tests/test_gi.py
index bc51c30a..39aaf0c6 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -2591,7 +2591,6 @@ class TestPythonGObject(unittest.TestCase):
 
     @unittest.skipUnless(hasattr(GIMarshallingTests, 'callback_owned_boxed'),
                          'requires newer version of GI')
-    @unittest.expectedFailure  # bug 722899
     def test_callback_owned_box(self):
         def callback(box, data):
             self.box = box


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