[pybank] Add support for interfaces
- From: Johan Dahlin <johan src gnome org>
- To: svn-commits-list gnome org
- Subject: [pybank] Add support for interfaces
- Date: Wed, 6 May 2009 10:16:20 -0400 (EDT)
commit 5bc86e4b48415128d8bcef9559ad6be8898535b9
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date: Wed May 6 15:16:32 2009 +0200
Add support for interfaces
---
bank/bank-info.c | 22 ++++++++++++++++++++++
bank/btypes.py | 26 ++++++++++++++++++++++++++
bank/module.py | 35 +++++++++++++++++++++++++++++++++--
everything_unittest.py | 5 +++++
4 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/bank/bank-info.c b/bank/bank-info.c
index 041ff06..77f6be4 100644
--- a/bank/bank-info.c
+++ b/bank/bank-info.c
@@ -601,7 +601,29 @@ static PyMethodDef _PyGIObjectInfo_methods[] = {
/* GIInterfaceInfo */
NEW_CLASS("InterfaceInfo", GIInterfaceInfo);
+static PyObject *
+_wrap_g_interface_info_get_methods(PyGIBaseInfo *self)
+{
+ int i, length;
+ PyObject *retval;
+
+ g_base_info_ref(self->info);
+ length = g_interface_info_get_n_methods((GIInterfaceInfo*)self->info);
+ retval = PyTuple_New(length);
+
+ for (i = 0; i < length; i++) {
+ GIFunctionInfo *function;
+ function = g_interface_info_get_method((GIInterfaceInfo*)self->info, i);
+ PyTuple_SetItem(retval, i, pyg_info_new(function));
+ g_base_info_unref((GIBaseInfo*)function);
+ }
+ g_base_info_unref(self->info);
+
+ return retval;
+}
+
static PyMethodDef _PyGIInterfaceInfo_methods[] = {
+ { "getMethods", (PyCFunction)_wrap_g_interface_info_get_methods, METH_NOARGS },
{ NULL, NULL, 0 }
};
diff --git a/bank/btypes.py b/bank/btypes.py
index c9a68da..8a8b35b 100644
--- a/bank/btypes.py
+++ b/bank/btypes.py
@@ -17,6 +17,8 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
+import gobject
+
import new
from bank import repo
@@ -255,4 +257,28 @@ def buildClass(info, bases):
return newType
+def buildInterface(info):
+ className = info.getName()
+ namespaceName = info.getNamespace()
+ fullName = namespaceName + '.' + className
+
+ if _classDict.has_key(fullName):
+ return _classDict[fullName]
+
+ namespace = {}
+ namespace['__info__'] = info
+ namespace['__module__'] = namespaceName
+ newType = type(className, (gobject.GInterface,), namespace)
+
+ for method in info.getMethods():
+ if method.isMethod():
+ methodName = method.getName()
+ setattr(newType, methodName, new.instancemethod(Method(method, className),
+ None, newType))
+ else:
+ raise ValueError('Interfaces can only have regular methods')
+
+ _classDict[fullName] = newType
+
+ return newType
diff --git a/bank/module.py b/bank/module.py
index 14bf656..523504c 100644
--- a/bank/module.py
+++ b/bank/module.py
@@ -22,8 +22,8 @@ import os
import gobject
from gobject import GEnum
-from .btypes import Function, buildClass
-from .repo import EnumInfo, FunctionInfo, ObjectInfo, UnresolvedInfo
+from .btypes import Function, buildClass, buildInterface
+from .repo import EnumInfo, FunctionInfo, ObjectInfo, UnresolvedInfo, InterfaceInfo
from .repository import repository
class DynamicModule(object):
@@ -83,6 +83,8 @@ class DynamicModule(object):
return self._create_enum(type_info)
elif isinstance(type_info, FunctionInfo):
return self._create_function(type_info)
+ elif isinstance(type_info, InterfaceInfo):
+ return self._create_interface(type_info)
else:
raise NotImplementedError(type_info)
@@ -150,3 +152,32 @@ class DynamicModule(object):
def _create_function(self, function_info):
return Function(function_info)
+
+ def _create_interface(self, interface_info):
+ name = interface_info.getName()
+
+ namespace = repository.get_c_prefix(interface_info.getNamespace())
+ full_name = namespace + name
+ interface_info.getGType()
+ gtype = None
+ try:
+ gtype = gobject.GType.from_name(full_name)
+ except RuntimeError:
+ pass
+ else:
+ if gtype.pytype is not None:
+ return gtype.pytype
+ # Check if the klass is already created, eg
+ # present in our namespace, this is necessary since we're
+ # not always entering here through the __getattr__ hook.
+ klass = self.__dict__.get(name)
+ if klass:
+ return klass
+
+ klass = buildInterface(interface_info)
+ if gtype is not None:
+ klass.__gtype__ = gtype
+ gtype.pytype = klass
+ self.__dict__[name] = klass
+
+ return klass
diff --git a/everything_unittest.py b/everything_unittest.py
index 7d946e4..384e590 100644
--- a/everything_unittest.py
+++ b/everything_unittest.py
@@ -252,5 +252,10 @@ class TestGIEverything(unittest.TestCase):
Everything.test_struct_b_clone(b, b_out)
self.assertEquals(b, b_out)
+ def testInterface(self):
+ self.assertTrue(issubclass(Everything.TestInterface, gobject.GInterface))
+ self.assertRaises(NotImplementedError, Everything.TestInterface)
+ self.assertEquals(Everything.TestInterface.__gtype__.name, 'EverythingTestInterface')
+
if __name__ == '__main__':
unittest.main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]