summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2011-08-25 13:57:53 -0400
committerJohn (J5) Palmieri <johnp@redhat.com>2011-08-30 14:12:33 -0400
commit429569abddada5a3bad554de707ddf35b349936e (patch)
treee9374249c452577e82c7c00a991cb505c62b98aa
parent7a234b185b131f3eb6a6e8a8c717ddf4d508b15e (diff)
downloadpygobject-429569abddada5a3bad554de707ddf35b349936e.tar.gz
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
-rw-r--r--gi/pygi-cache.c1
-rw-r--r--gi/pygi-cache.h1
-rw-r--r--gi/pygi-invoke.c48
-rw-r--r--tests/test_everything.py8
4 files changed, 40 insertions, 18 deletions
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 31dc9e2e..a3764435 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 e00e54d3..a0e6e4f2 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 55e56ee5..4a7366c2 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 57dbd4c6..4a03890c 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);