Skip to content

Commit

Permalink
[gi] marshal raw closures
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
John (J5) Palmieri committed Mar 21, 2011
1 parent ac11dc7 commit f5ee292
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
15 changes: 10 additions & 5 deletions gi/pygi-argument.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1072,10 +1073,14 @@ _pygi_argument_from_object (PyObject *object,
} else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
GClosure *closure;

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;
Expand Down
4 changes: 4 additions & 0 deletions tests/test_gi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit f5ee292

Please sign in to comment.