[pygobject] Speed up _setup_native_vfuncs()
- From: Laszlo Pandy <lpandy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Speed up _setup_native_vfuncs()
- Date: Wed, 26 Jan 2011 17:34:36 +0000 (UTC)
commit b15e8e2c0c933d0f827a70280faf875ac383d81b
Author: Laszlo Pandy <lpandy src gnome org>
Date: Wed Jan 26 00:40:49 2011 +0100
Speed up _setup_native_vfuncs()
This changes _setup_native_vfuncs() to only install native
vfunc wrappers from the current class on the current class.
Native vfuncs will not be propogated up or down the class
hierarchy as this is unnecessary and wastes CPU and memory.
Since the normal process in python to retrieve a method or
attribute recurses to the base classes if an attribute is not
found in the subclass, there is no need to setup all base class
virtual functions on a subclass.
This patch removes the recursion in _setup_native_vfuncs()
and lets Python find them in the base classes like a normal
Python class would work. This significantly increases the speed
of any class which is or inherits from a C class which includes
virtual methods.
https://bugzilla.gnome.org/show_bug.cgi?id=640629
gi/types.py | 26 +++++++++++++-------------
tests/test_gi.py | 13 +++++++++++++
2 files changed, 26 insertions(+), 13 deletions(-)
---
diff --git a/gi/types.py b/gi/types.py
index 6e486e7..b3a9d3d 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -149,19 +149,19 @@ class MetaClassHelper(object):
hook_up_vfunc_implementation(vfunc_info, cls.__gtype__,
py_vfunc)
- def _setup_native_vfuncs(cls, impl):
- for base in cls.__bases__ + (cls,):
- if not hasattr(base, '__info__') or \
- not hasattr(base.__info__, 'get_vfuncs') or \
- isinstance(base.__info__, InterfaceInfo):
- continue
- for vfunc_info in base.__info__.get_vfuncs():
- name = 'do_%s' % vfunc_info.get_name()
- value = NativeVFunc(vfunc_info, impl)
- setattr(impl, name, value)
+ def _setup_native_vfuncs(cls):
+ # Only InterfaceInfo and ObjectInfo have the get_vfuncs() method.
+ # We skip InterfaceInfo because interfaces have no implementations for vfuncs.
+ # Also check if __info__ in __dict__, not hasattr('__info__', ...)
+ # because we do not want to accidentally retrieve __info__ from a base class.
+ class_info = cls.__dict__.get('__info__')
+ if class_info is None or not isinstance(class_info, ObjectInfo):
+ return
- if base != cls:
- base._setup_native_vfuncs(impl)
+ for vfunc_info in class_info.get_vfuncs():
+ name = 'do_%s' % vfunc_info.get_name()
+ value = NativeVFunc(vfunc_info, cls)
+ setattr(cls, name, value)
def find_vfunc_info_in_interface(bases, vfunc_name):
for base in bases:
@@ -215,7 +215,7 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
elif is_gi_defined:
cls._setup_methods()
cls._setup_constants()
- cls._setup_native_vfuncs(cls)
+ cls._setup_native_vfuncs()
if isinstance(cls.__info__, ObjectInfo):
cls._setup_fields()
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 08899c4..19a7d46 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -1447,6 +1447,19 @@ class TestPythonGObject(unittest.TestCase):
object_ = ObjectOverrideNonVFuncDoMethod()
self.assertEquals(18, object_.do_not_a_vfunc())
+ def test_native_function_not_set_in_subclass_dict(self):
+ # Previously, GI was setting virtual functions on the class as well
+ # as any *native* class that subclasses it. Here we check that it is only
+ # set on the class that the method is originally from.
+ 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.
+ self.assertTrue(GIMarshallingTests.Object.do_method_with_default_implementation.im_func is \
+ GIMarshallingTests.SubObject.do_method_with_default_implementation.im_func)
+
+
class TestMultiOutputArgs(unittest.TestCase):
def test_int_out_out(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]