diff options
author | John (J5) Palmieri <johnp@redhat.com> | 2011-08-25 13:57:53 -0400 |
---|---|---|
committer | John (J5) Palmieri <johnp@redhat.com> | 2011-08-30 14:12:33 -0400 |
commit | 429569abddada5a3bad554de707ddf35b349936e (patch) | |
tree | e9374249c452577e82c7c00a991cb505c62b98aa | |
parent | 7a234b185b131f3eb6a6e8a8c717ddf4d508b15e (diff) | |
download | pygobject-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.c | 1 | ||||
-rw-r--r-- | gi/pygi-cache.h | 1 | ||||
-rw-r--r-- | gi/pygi-invoke.c | 48 | ||||
-rw-r--r-- | 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 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); |