[pygobject] Don't pass None to callbacks when user data is not specified



commit 73c6213e8b47fa7c4c2c7a517fe7b56126145888
Author: Simon Feltman <sfeltman src gnome org>
Date:   Thu Sep 26 19:05:20 2013 -0700

    Don't pass None to callbacks when user data is not specified
    
    For APIs which support a callback and optional user data,
    don't pass the user data to the callback if it was not explicitly
    specified when the callback was connected.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=640812

 gi/pygi-closure.c         |   17 ++++++++++++++---
 gi/pygi-marshal-from-py.c |    5 -----
 tests/test_everything.py  |    7 ++-----
 3 files changed, 16 insertions(+), 13 deletions(-)
---
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 2f5548a..bfd6d0d 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -368,7 +368,18 @@ _pygi_closure_convert_arguments (GICallableInfo *callable_info, void **args,
             if (direction == GI_DIRECTION_IN && arg_tag == GI_TYPE_TAG_VOID &&
                     g_type_info_is_pointer (&arg_type)) {
 
-                if (user_data == NULL) {
+                if (user_data == _PyGIDefaultArgPlaceholder) {
+                    /* When user data is a place holder, skip handing anything to the callback.
+                     * This happens when the callback connect function accepts user data
+                     * but nothing was passed in.
+                     */
+                    continue;
+                } else if (user_data == NULL) {
+                    /* user data can be NULL for connect functions which don't accept
+                     * user data but we still need to pass None to the callbacks for
+                     * compatibility of setups prior to _PyGIDefaultArgPlaceholder.
+                     * For example: Regress.test_async_ready_callback
+                     */
                     Py_INCREF (Py_None);
                     value = Py_None;
                 } else {
@@ -631,10 +642,10 @@ _pygi_make_native_closure (GICallableInfo* info,
     closure = g_slice_new0 (PyGICClosure);
     closure->info = (GICallableInfo *) g_base_info_ref ( (GIBaseInfo *) info);
     closure->function = py_function;
-    closure->user_data = py_user_data ? py_user_data : Py_None;
+    closure->user_data = py_user_data;
 
     Py_INCREF (py_function);
-    Py_INCREF (closure->user_data);
+    Py_XINCREF (closure->user_data);
 
     fficlosure =
         g_callable_info_prepare_closure (info, &closure->cif, _pygi_closure_handle,
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index 22571ef..73356b1 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -1255,11 +1255,6 @@ _pygi_marshal_from_py_interface_callback (PyGIInvokeState   *state,
             py_user_data = PyTuple_GetItem (state->py_in_args, user_data_cache->py_arg_index);
             if (!py_user_data)
                 return FALSE;
-            /* NULL out user_data if it was not supplied and the default arg placeholder
-             * was used instead.
-             */
-            if (py_user_data == _PyGIDefaultArgPlaceholder)
-                py_user_data = NULL;
         }
     }
 
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 0c6533a..ab1fc48 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -717,12 +717,10 @@ class TestCallbacks(unittest.TestCase):
 
         self.assertEqual(TestCallbacks.called, 100)
 
-    def test_callback_userdata_none_default_arg(self):
+    def test_callback_userdata_no_user_data(self):
         TestCallbacks.called = 0
-        userdata_list = []
 
-        def callback(userdata):
-            userdata_list.append(userdata)
+        def callback():
             TestCallbacks.called += 1
             return TestCallbacks.called
 
@@ -731,7 +729,6 @@ class TestCallbacks(unittest.TestCase):
             self.assertEqual(val, i + 1)
 
         self.assertEqual(TestCallbacks.called, 100)
-        self.assertSequenceEqual(userdata_list, [None] * 100)
 
     def test_async_ready_callback(self):
         TestCallbacks.called = False


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