Commit 429569ab authored by John (J5) Palmieri's avatar John (J5) Palmieri

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
parent 7a234b18
......@@ -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);
......
......@@ -87,6 +87,7 @@ struct _PyGIArgCache
PyGIMetaArgType meta_type;
gboolean is_pointer;
gboolean is_caller_allocates;
gboolean is_skipped;
gboolean allow_none;
GIDirection direction;
......
......@@ -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);
}
}
}
......
......@@ -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);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment