[pygobject] Fix regression in marshalling partial() objects



commit c45eec02185b425e353f5fc477b04567d9627fcb
Author: Christoph Reiter <reiter christoph gmail com>
Date:   Tue Mar 30 07:54:42 2021 +0200

    Fix regression in marshalling partial() objects
    
    In a4880dbc4575fadc0e3 a special case for partial() was added to handle gtk4 template
    callbacks. This in turn broken normal usage of partial objects.
    
    To work around that add a special marker in the gtk template code for now until
    we find a better fix.
    
    Also adds a test so this doesn't happen again.
    
    Fixes #464

 gi/_gtktemplate.py       |  7 +++++--
 gi/pygi-struct-marshal.c |  2 +-
 tests/test_gi.py         | 16 ++++++++++++++++
 3 files changed, 22 insertions(+), 3 deletions(-)
---
diff --git a/gi/_gtktemplate.py b/gi/_gtktemplate.py
index a631a6eb..925aa0dd 100644
--- a/gi/_gtktemplate.py
+++ b/gi/_gtktemplate.py
@@ -78,9 +78,12 @@ def define_builder_scope():
             handler, args = _extract_handler_and_args(current_object, handler_name)
 
             if obj:
-                return partial(handler, *args, swap_data=obj)
+                p = partial(handler, *args, swap_data=obj)
+            else:
+                p = partial(handler, *args)
 
-            return partial(handler, *args)
+            p.__gtk_template__ = True
+            return p
 
     return BuilderScope
 
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 0e190b8e..a3eb2802 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -191,7 +191,7 @@ pygi_arg_gclosure_from_py_marshal (PyObject   *py_arg,
             Py_DECREF (functools);
         }
 
-        if (partial && PyObject_IsInstance (py_arg, partial) > 0) {
+        if (partial && PyObject_IsInstance (py_arg, partial) > 0 && PyObject_HasAttrString (py_arg, 
"__gtk_template__")) {
             PyObject *partial_func;
             PyObject *partial_args;
             PyObject *partial_keywords;
diff --git a/tests/test_gi.py b/tests/test_gi.py
index f6552665..5979d5d0 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -1692,6 +1692,22 @@ class TestGClosure(unittest.TestCase):
     def test_in(self):
         GIMarshallingTests.gclosure_in(lambda: 42)
 
+    def test_in_partial(self):
+        from functools import partial
+
+        called_args = []
+        called_kwargs = {}
+
+        def callback(*args, **kwargs):
+            called_args.extend(args)
+            called_kwargs.update(kwargs)
+            return 42
+
+        func = partial(callback, 1, 2, 3, foo=42)
+        GIMarshallingTests.gclosure_in(func)
+        assert called_args == [1, 2, 3]
+        assert called_kwargs["foo"] == 42
+
     def test_pass(self):
         # test passing a closure between two C calls
         closure = GIMarshallingTests.gclosure_return()


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