[pygobject/gsoc2009: 53/160] Add G(S)List support as input argument
- From: Simon van der Linden <svdlinden src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pygobject/gsoc2009: 53/160] Add G(S)List support as input argument
- Date: Fri, 14 Aug 2009 21:26:32 +0000 (UTC)
commit b786a00bca61d01ec31d5d507cbecafb88980974
Author: Simon van der Linden <svdlinden src gnome org>
Date: Wed Jul 22 15:37:24 2009 +0200
Add G(S)List support as input argument
gi/pygargument.c | 106 ++++++++++++++++++++++++++++++++++++++++++--
tests/test_girepository.py | 24 +++++++++-
2 files changed, 124 insertions(+), 6 deletions(-)
---
diff --git a/gi/pygargument.c b/gi/pygargument.c
index c94de9a..56703f6 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -363,6 +363,54 @@ check_number_clean:
g_base_info_unref(info);
break;
}
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ GITypeInfo *item_type_info;
+ Py_ssize_t length;
+ Py_ssize_t i;
+
+ if (!PySequence_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be sequence, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ retval = -1;
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+
+ for (i = 0; i < length; i++) {
+ PyObject *item;
+
+ item = PySequence_GetItem(object, i);
+ if (item == NULL) {
+ retval = -1;
+ break;
+ }
+
+ retval = pygi_gi_type_info_check_py_object(item_type_info, item);
+
+ Py_DECREF(item);
+
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ PyErr_PREFIX_FROM_FORMAT("Item %zd :", i);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+
+ break;
+ }
case GI_TYPE_TAG_GTYPE:
{
gint is_instance;
@@ -381,8 +429,6 @@ check_number_clean:
break;
}
case GI_TYPE_TAG_TIME_T:
- case GI_TYPE_TAG_GLIST:
- case GI_TYPE_TAG_GSLIST:
case GI_TYPE_TAG_GHASH:
case GI_TYPE_TAG_ERROR:
/* TODO */
@@ -455,8 +501,11 @@ GArgument
pygi_g_argument_from_py_object(PyObject *object, GITypeInfo *type_info)
{
GArgument arg;
+ GITypeTag type_tag;
+
+ type_tag = g_type_info_get_tag(type_info);
- switch (g_type_info_get_tag(type_info))
+ switch (type_tag)
{
case GI_TYPE_TAG_VOID:
/* Nothing to do */
@@ -685,6 +734,54 @@ array_clean:
g_base_info_unref((GIBaseInfo *)item_type_info);
break;
}
+ case GI_TYPE_TAG_GLIST:
+ case GI_TYPE_TAG_GSLIST:
+ {
+ Py_ssize_t length;
+ GITypeInfo *item_type_info;
+ GSList *list = NULL;
+ Py_ssize_t i;
+
+ length = PySequence_Length(object);
+ if (length < 0) {
+ break;
+ }
+
+ item_type_info = g_type_info_get_param_type(type_info, 0);
+
+ for (i = length - 1; i >= 0; i--) {
+ PyObject *py_item;
+ GArgument item;
+
+ py_item = PySequence_GetItem(object, i);
+ if (py_item == NULL) {
+ /* TODO: free the previous items */
+ break;
+ }
+
+ item = pygi_g_argument_from_py_object(py_item, item_type_info);
+
+ Py_DECREF(py_item);
+
+ if (PyErr_Occurred()) {
+ /* TODO: free the previous items */
+ PyErr_PREFIX_FROM_FORMAT("Item %zd :", i);
+ break;
+ }
+
+ if (type_tag == GI_TYPE_TAG_GLIST) {
+ list = (GSList *)g_list_prepend((GList *)list, item.v_pointer);
+ } else {
+ list = g_slist_prepend(list, item.v_pointer);
+ }
+ }
+
+ arg.v_pointer = list;
+
+ g_base_info_unref((GIBaseInfo *)item_type_info);
+
+ break;
+ }
case GI_TYPE_TAG_ERROR:
/* Allow NULL GError, otherwise fall through */
if (object == Py_None) {
@@ -944,7 +1041,7 @@ struct_error_clean:
item_type_info = g_type_info_get_param_type(type_info, 0);
- for (i = 0; list != NULL; list = (GSList *)list->next, i++) {
+ for (i = 0; list != NULL; list = g_slist_next(list), i++) {
GArgument item;
PyObject *py_item;
@@ -954,6 +1051,7 @@ struct_error_clean:
if (py_item == NULL) {
Py_DECREF(object);
object = NULL;
+ PyErr_PREFIX_FROM_FORMAT("Item %zd :", i);
break;
}
diff --git a/tests/test_girepository.py b/tests/test_girepository.py
index 945491c..97faed3 100644
--- a/tests/test_girepository.py
+++ b/tests/test_girepository.py
@@ -379,15 +379,35 @@ class TestGIEverything(unittest.TestCase):
# Interface
# GList
- def testGList(self):
+ def testGListReturn(self):
self.assertEqual(list(test_sequence), Everything.test_glist_nothing_return())
+ def testGListIn(self):
+ Everything.test_glist_nothing_in(test_sequence)
+
+ # Test as string, which implements the sequence protocol too.
+ Everything.test_glist_nothing_in('123')
+
+ # Test type checking.
+ self.assertRaises(TypeError, Everything.test_glist_nothing_in, 1)
+ self.assertRaises(TypeError, Everything.test_glist_nothing_in, (1, 2, 3))
+
# GSList
- def testGSList(self):
+ def testGSListReturn(self):
self.assertEqual(list(test_sequence), Everything.test_gslist_nothing_return())
+ def testGSListIn(self):
+ Everything.test_gslist_nothing_in(test_sequence)
+
+ # Test as string, which implements the sequence protocol too.
+ Everything.test_gslist_nothing_in('123')
+
+ # Test type checking.
+ self.assertRaises(TypeError, Everything.test_gslist_nothing_in, 1)
+ self.assertRaises(TypeError, Everything.test_gslist_nothing_in, (1, 2, 3))
+
# closure
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]