[pygobject] support skip annotation for return values



commit 429569abddada5a3bad554de707ddf35b349936e
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu Aug 25 13:57:53 2011 -0400

    support skip annotation for return values
    
    * this is used for things like skiping gboolean returns that are
      useful is C but useless in python
    
    * cleans up after skipped returns that are also marked transfer
      full
    https://bugzilla.gnome.org/show_bug.cgi?id=650135

 gi/pygi-cache.c          |    1 +
 gi/pygi-cache.h          |    1 +
 gi/pygi-invoke.c         |   48 ++++++++++++++++++++++++++++-----------------
 tests/test_everything.py |    8 +++++++
 4 files changed, 40 insertions(+), 18 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 31dc9e2..a376443 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -1265,6 +1265,7 @@ _args_cache_generate (GICallableInfo *callable_info,
                         -1,
                         -1);
 
+    return_cache->is_skipped = g_callable_info_skip_return (callable_info);
     callable_cache->return_cache = return_cache;
     g_base_info_unref (return_info);
 
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index e00e54d..a0e6e4f 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -87,6 +87,7 @@ struct _PyGIArgCache
     PyGIMetaArgType meta_type;
     gboolean is_pointer;
     gboolean is_caller_allocates;
+    gboolean is_skipped;
     gboolean allow_none;
 
     GIDirection direction;
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 55e56ee..4a7366c 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -24,7 +24,7 @@
 
 #include <pyglib.h>
 #include "pygi-invoke.h"
-
+#include "pygi-marshal-cleanup.h"
 
 static inline gboolean
 _invoke_callable (PyGIInvokeState *state,
@@ -508,30 +508,42 @@ _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
     gboolean has_return = FALSE;
 
     if (cache->return_cache) {
+        if (!cache->return_cache->is_skipped) {
+            if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
+                if (state->return_arg.v_pointer == NULL) {
+                    PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
+                    pygi_marshal_cleanup_args_return_fail (state,
+                                                       cache);
+                    return NULL;
+                }
+            }
 
-        if (cache->function_type == PYGI_FUNCTION_TYPE_CONSTRUCTOR) {
-            if (state->return_arg.v_pointer == NULL) {
-                PyErr_SetString (PyExc_TypeError, "constructor returned NULL");
+            py_return = cache->return_cache->out_marshaller ( state,
+                                                              cache,
+                                                              cache->return_cache,
+                                                             &state->return_arg);
+            if (py_return == NULL) {
                 pygi_marshal_cleanup_args_return_fail (state,
                                                        cache);
                 return NULL;
             }
-        }
 
-        py_return = cache->return_cache->out_marshaller ( state,
-                                                          cache,
-                                                          cache->return_cache,
-                                                         &state->return_arg);
-        if (py_return == NULL) {
-            pygi_marshal_cleanup_args_return_fail (state,
-                                                   cache);
-            return NULL;
-        }
 
-
-        if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
-            total_out_args++;
-            has_return = TRUE;
+            if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
+                total_out_args++;
+                has_return = TRUE;
+            }
+        } else {
+            if (cache->return_cache->transfer == GI_TRANSFER_EVERYTHING) {
+                PyGIMarshalCleanupFunc out_cleanup =
+                    cache->return_cache->out_cleanup;
+
+                if (out_cleanup != NULL)
+                    out_cleanup ( state,
+                                  cache->return_cache,
+                                 &state->return_arg,
+                                  FALSE);
+            }
         }
     }
 
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 57dbd4c..4a03890 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -475,3 +475,11 @@ class TestAdvancedInterfaces(unittest.TestCase):
         self.assertTrue(isinstance(obj1, Everything.TestObj))
         self.assertTrue(isinstance(obj2, Everything.TestObj))
         self.assertNotEqual(obj1, obj2)
+
+    def test_obj_skip_return_val(self):
+        obj = Everything.TestObj();
+        ret = obj.skip_return_val(50, 42.0, 60, 2, 3);
+        self.assertEquals(len(ret), 3);
+        self.assertEquals(ret[0], 51);
+        self.assertEquals(ret[1], 61);
+        self.assertEquals(ret[2], 32);



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