[pybank] Implement incoming lists handling
- From: Johan Dahlin <johan src gnome org>
- To: svn-commits-list gnome org
- Subject: [pybank] Implement incoming lists handling
- Date: Tue, 2 Jun 2009 10:45:43 -0400 (EDT)
commit 6f7df17e7f306d4ffe0c5cb86d39141ff6b33a13
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date: Thu May 14 10:21:04 2009 +0200
Implement incoming lists handling
---
bank/bank-argument.c | 158 ++++++++++++++++++++++++++++++------------------
everything_unittest.py | 14 +++-
2 files changed, 109 insertions(+), 63 deletions(-)
diff --git a/bank/bank-argument.c b/bank/bank-argument.c
index c2870d4..464be8c 100644
--- a/bank/bank-argument.c
+++ b/bank/bank-argument.c
@@ -21,7 +21,6 @@
#include "bank.h"
#include <pygobject.h>
-
GArgument
pyg_argument_from_pyobject(PyObject *object, GITypeInfo *type_info)
{
@@ -113,76 +112,81 @@ pyg_argument_from_pyobject(PyObject *object, GITypeInfo *type_info)
return arg;
}
-PyObject *
-pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
+static PyObject *
+glist_to_pyobject(GITypeTag list_tag, GITypeInfo *type_info, GList *list, GSList *slist)
{
- GITypeTag type_tag;
- PyObject *obj;
- GIBaseInfo* interface_info;
- GIInfoType interface_type;
-
- g_return_val_if_fail(type_info != NULL, NULL);
- type_tag = g_type_info_get_tag(type_info);
- if ( type_tag == GI_TYPE_TAG_INTERFACE ) {
- interface_info = g_type_info_get_interface(type_info);
- interface_type = g_base_info_get_type(interface_info);
+ PyObject *py_list;
+ int i;
+ GArgument arg;
+ PyObject *child_obj;
- if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_BOXED) {
- // Create new struct based on arg->v_pointer
- const gchar *module_name = g_base_info_get_namespace(interface_info);
- const gchar *type_name = g_base_info_get_name(interface_info);
- PyObject *module = PyImport_ImportModule(module_name);
- PyObject *tp = PyObject_GetAttrString(module, type_name);
- gsize size;
- PyObject *buffer;
- PyObject **dict;
+ if ((py_list = PyList_New(0)) == NULL) {
+ g_list_free(list);
+ return NULL;
+ }
+ i = 0;
+ if (list_tag == GI_TYPE_TAG_GLIST) {
+ for ( ; list != NULL; list = list->next) {
+ arg.v_pointer = list->data;
- if (tp == NULL) {
- char buf[256];
- snprintf(buf, sizeof(buf), "Type %s.%s not defined", module_name, type_name);
- PyErr_SetString(PyExc_TypeError, buf);
- return NULL;
- }
+ child_obj = pyg_argument_to_pyobject(&arg, type_info);
- obj = PyObject_New(PyObject, (PyTypeObject *) tp);
- if (obj == NULL)
+ if (child_obj == NULL) {
+ g_list_free(list);
+ Py_DECREF(py_list);
return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
- // FIXME: Any better way to initialize the dict pointer?
- dict = (PyObject **) ((char *)obj + ((PyTypeObject *) tp)->tp_dictoffset);
- *dict = NULL;
+ ++i;
+ }
+ } else {
+ for ( ; slist != NULL; slist = slist->next) {
+ arg.v_pointer = slist->data;
- size = g_struct_info_get_size ((GIStructInfo*)type_info);
- buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
+ child_obj = pyg_argument_to_pyobject(&arg, type_info);
- PyObject_SetAttrString(obj, "__buffer__", buffer);
+ if (child_obj == NULL) {
+ g_list_free(list);
+ Py_DECREF(py_list);
+ return NULL;
+ }
+ PyList_Append(py_list, child_obj);
+ Py_DECREF(child_obj);
- Py_INCREF(obj);
- return obj;
- } else if (interface_type == GI_INFO_TYPE_ENUM) {
- g_warning("pyg_argument_to_pyobject: enums not implemented");
- obj = Py_None;
- Py_INCREF(obj);
- return obj;
- } else if ( arg->v_pointer == NULL ) {
- obj = Py_None;
- Py_INCREF(obj);
- return obj;
- } else {
- GValue value;
- GObject* obj = arg->v_pointer;
- GType gtype = G_OBJECT_TYPE(obj);
- value.g_type = gtype;
- value.data[0].v_pointer = obj;
- return pyg_value_as_pyobject(&value, FALSE);
- }
+ ++i;
+ }
}
+ g_list_free(list);
+ return py_list;
+}
+
+PyObject *
+pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
+{
+ GITypeTag type_tag;
+ PyObject *obj;
+ GIBaseInfo* interface_info;
+ GIInfoType interface_type;
+ GITypeInfo *param_info;
+
+ g_return_val_if_fail(type_info != NULL, NULL);
+ type_tag = g_type_info_get_tag(type_info);
switch (type_tag) {
case GI_TYPE_TAG_VOID:
+ obj = Py_None;
+ break;
case GI_TYPE_TAG_GLIST:
- obj = Py_None;
- break;
+ case GI_TYPE_TAG_GSLIST:
+ param_info = g_type_info_get_param_type(type_info, 0);
+ g_assert(param_info != NULL);
+ obj = glist_to_pyobject(type_tag,
+ param_info,
+ type_tag == GI_TYPE_TAG_GLIST ? arg->v_pointer : NULL,
+ type_tag == GI_TYPE_TAG_GSLIST ? arg->v_pointer : NULL);
+ break;
case GI_TYPE_TAG_BOOLEAN:
obj = PyBool_FromLong(arg->v_boolean);
break;
@@ -235,8 +239,44 @@ pyg_argument_to_pyobject(GArgument *arg, GITypeInfo *type_info)
obj = PyString_FromString(arg->v_string);
break;
case GI_TYPE_TAG_INTERFACE:
- obj = PyCObject_FromVoidPtr(arg->v_pointer, NULL);
- break;
+ interface_info = g_type_info_get_interface(type_info);
+ interface_type = g_base_info_get_type(interface_info);
+
+ if (interface_type == GI_INFO_TYPE_STRUCT || interface_type == GI_INFO_TYPE_BOXED) {
+ // Create new struct based on arg->v_pointer
+ const gchar *module_name = g_base_info_get_namespace(interface_info);
+ const gchar *type_name = g_base_info_get_name(interface_info);
+ PyObject *module = PyImport_ImportModule(module_name);
+ PyObject *tp = PyObject_GetAttrString(module, type_name);
+ gsize size;
+ PyObject *buffer;
+ PyObject **dict;
+
+ if (tp == NULL) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "Type %s.%s not defined", module_name, type_name);
+ PyErr_SetString(PyExc_TypeError, buf);
+ return NULL;
+ }
+
+ obj = PyObject_New(PyObject, (PyTypeObject *) tp);
+ if (obj == NULL)
+ return NULL;
+
+ // FIXME: Any better way to initialize the dict pointer?
+ dict = (PyObject **) ((char *)obj + ((PyTypeObject *) tp)->tp_dictoffset);
+ *dict = NULL;
+
+ size = g_struct_info_get_size ((GIStructInfo*)type_info);
+ buffer = PyBuffer_FromReadWriteMemory(arg->v_pointer, size);
+
+ PyObject_SetAttrString(obj, "__buffer__", buffer);
+
+ } else if (interface_type == GI_INFO_TYPE_ENUM) {
+ g_warning("pyg_argument_to_pyobject: enums not implemented");
+ obj = Py_None;
+ }
+ break;
case GI_TYPE_TAG_ARRAY:
obj = Py_None;
break;
diff --git a/everything_unittest.py b/everything_unittest.py
index d2bb68a..fd245f0 100644
--- a/everything_unittest.py
+++ b/everything_unittest.py
@@ -180,13 +180,19 @@ class TestGIEverything(unittest.TestCase):
self.assertRaises(TypeError, Everything.test_strv_in(('1', 2, 3)))
self.assertEquals((1, 2, 3), Everything.test_strv_out())
- # TODO add more asserts
def testGList(self):
- self.assertTrue(isinstance(Everything.test_glist_nothing_return(), GLib.List))
+ retval = Everything.test_glist_nothing_return()
+ self.assertTrue(isinstance(retval, list))
+ self.assertEquals(retval[0], '1')
+ self.assertEquals(retval[1], '2')
+ self.assertEquals(retval[2], '3')
- # TODO add more asserts
def testGSList(self):
- self.assertTrue(isinstance(Everything.test_gslist_nothing_return(), GLib.SList))
+ retval = Everything.test_gslist_nothing_return()
+ self.assertTrue(isinstance(retval, list))
+ self.assertEquals(retval[0], '1')
+ self.assertEquals(retval[1], '2')
+ self.assertEquals(retval[2], '3')
# XXX Currently causes a segfault.
# def testClosure(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]