[pygobject] Properly chain up to the class that implements a given vfunc.



commit 2fd3aa9d4ca0906a5e609845ee500ba72e358f94
Author: Tomeu Vizoso <tomeu vizoso collabora com>
Date:   Sat Oct 29 15:08:03 2011 +0200

    Properly chain up to the class that implements a given vfunc.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=662994

 gi/types.py      |   22 +++++++++++++---------
 tests/test_gi.py |   20 ++++++++++----------
 2 files changed, 23 insertions(+), 19 deletions(-)
---
diff --git a/gi/types.py b/gi/types.py
index 58eec51..f767e3c 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -48,15 +48,20 @@ def Function(info):
     return function
 
 
-def NativeVFunc(info, cls):
+class NativeVFunc(object):
 
-    def native_vfunc(*args, **kwargs):
-        return info.invoke(cls.__gtype__, *args, **kwargs)
-    native_vfunc.__info__ = info
-    native_vfunc.__name__ = info.get_name()
-    native_vfunc.__module__ = info.get_namespace()
+    def __init__(self, info):
+        self._info = info
+
+    def __get__(self, instance, klass):
+        def native_vfunc(*args, **kwargs):
+            return self._info.invoke(klass.__gtype__, *args, **kwargs)
+        native_vfunc.__info__ = self._info
+        native_vfunc.__name__ = self._info.get_name()
+        native_vfunc.__module__ = self._info.get_namespace()
+
+        return native_vfunc
 
-    return native_vfunc
 
 def Constructor(info):
 
@@ -147,7 +152,6 @@ class MetaClassHelper(object):
                              base_info.get_name(),
                              ambiguous_base.__info__.get_namespace(),
                              ambiguous_base.__info__.get_name()))
-
                 hook_up_vfunc_implementation(vfunc_info, cls.__gtype__,
                                              py_vfunc)
 
@@ -162,7 +166,7 @@ class MetaClassHelper(object):
 
         for vfunc_info in class_info.get_vfuncs():
             name = 'do_%s' % vfunc_info.get_name()
-            value = NativeVFunc(vfunc_info, cls)
+            value = NativeVFunc(vfunc_info)
             setattr(cls, name, value)
 
 def find_vfunc_info_in_interface(bases, vfunc_name):
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 11ee2a4..c32cdab 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -1639,16 +1639,6 @@ class TestPythonGObject(unittest.TestCase):
         self.assertTrue('do_method_with_default_implementation' in GIMarshallingTests.Object.__dict__)
         self.assertTrue('do_method_with_default_implementation' not in GIMarshallingTests.SubObject.__dict__)
 
-        # Here we check that accessing a vfunc from the subclass returns the same wrapper object,
-        # meaning that multiple wrapper objects have not been created for the same vfunc.
-        func1 = GIMarshallingTests.Object.do_method_with_default_implementation
-        func2 = GIMarshallingTests.SubObject.do_method_with_default_implementation
-        if sys.version_info < (3,0):
-            func1 = func1.im_func
-            func2 = func2.im_func
-            
-        self.assertTrue(func1 is func2)
-
     def test_subobject_with_interface_and_non_vfunc_do_method(self):
         # There was a bug for searching for vfuncs in interfaces. It was
         # triggered by having a do_* method that wasn't overriding
@@ -1657,6 +1647,16 @@ class TestPythonGObject(unittest.TestCase):
             def do_method_not_a_vfunc(self):
                 pass
 
+    def test_subsubobject(self):
+        class SubSubSubObject(GIMarshallingTests.SubSubObject):
+            def do_method_deep_hierarchy(self, num):
+                self.props.int = num * 2
+
+        sub_sub_sub_object = SubSubSubObject()
+        GIMarshallingTests.SubSubObject.do_method_deep_hierarchy(sub_sub_sub_object, 5)
+        self.assertEqual(sub_sub_sub_object.props.int, 5)
+
+
 class TestMultiOutputArgs(unittest.TestCase):
 
     def test_int_out_out(self):



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