[pygobject] [gi] marshal raw closures



commit 62b49dae97441953452d097cb1751df14302547a
Author: John (J5) Palmieri <johnp redhat com>
Date:   Wed Mar 16 17:34:18 2011 -0400

    [gi] marshal raw closures
    
    * before we were able to marshal python callables into methods that took
      GClosures but we had no way to take a GClosure returned from one
      method and pass it to another - this enables that usecase
    
    https://bugzilla.gnome.org/show_bug.cgi?id=644757

 gi/pygi-argument.c |   17 ++++++++++-------
 tests/test_gi.py   |    4 ++++
 2 files changed, 14 insertions(+), 7 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index bbbad00..c44307c 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -224,7 +224,8 @@ _pygi_g_type_interface_check_object (GIBaseInfo *info,
             /* Handle special cases. */
             type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
             if (g_type_is_a (type, G_TYPE_CLOSURE)) {
-                if (!PyCallable_Check (object)) {
+                if (!(PyCallable_Check (object) ||
+                      pyg_type_from_object_strict (object, FALSE) == G_TYPE_CLOSURE)) {
                     PyErr_Format (PyExc_TypeError, "Must be callable, not %s",
                                   object->ob_type->tp_name);
                     retval = 0;
@@ -1072,12 +1073,14 @@ array_success:
                     } else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
                         GClosure *closure;
 
-                        g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
-
-                        closure = pyg_closure_new (object, NULL, NULL);
-                        if (closure == NULL) {
-                            PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
-                            break;
+                        if (pyg_type_from_object_strict (object, FALSE) == G_TYPE_CLOSURE) {
+                            closure = (GClosure *)pyg_boxed_get (object, void);
+                        } else {
+                            closure = pyg_closure_new (object, NULL, NULL);
+                            if (closure == NULL) {
+                                PyErr_SetString (PyExc_RuntimeError, "PyObject conversion to GClosure failed");
+                                break;
+                            }
                         }
 
                         arg.v_pointer = closure;
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 73eb6fc..4aa5532 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -945,6 +945,10 @@ class TestGClosure(unittest.TestCase):
     def test_gclosure_in(self):
         GIMarshallingTests.gclosure_in(lambda: 42)
 
+        # test passing a closure between two C calls
+        closure = GIMarshallingTests.gclosure_return()
+        GIMarshallingTests.gclosure_in(closure)
+
         self.assertRaises(TypeError, GIMarshallingTests.gclosure_in, 42)
         self.assertRaises(TypeError, GIMarshallingTests.gclosure_in, None)
 



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