[pygobject/gsoc2009: 54/160] Add GHashTable support as input/output/return argument
- From: Simon van der Linden <svdlinden src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pygobject/gsoc2009: 54/160] Add GHashTable support as input/output/return argument
- Date: Fri, 14 Aug 2009 21:26:37 +0000 (UTC)
commit d37c546c06adc4817c99acbcbdd717cff3c3f964
Author: Simon van der Linden <svdlinden src gnome org>
Date: Wed Jul 22 17:46:37 2009 +0200
Add GHashTable support as input/output/return argument
gi/pygargument.c | 217 +++++++++++++++++++++++++++++++++++++++++++-
tests/test_girepository.py | 15 +++
2 files changed, 231 insertions(+), 1 deletions(-)
---
diff --git a/gi/pygargument.c b/gi/pygargument.c
index 56703f6..f39476d 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -411,6 +411,76 @@ check_number_clean:
break;
}
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ PyObject *keys;
+ PyObject *values;
+ Py_ssize_t length;
+ Py_ssize_t i;
+
+ if (!PyMapping_Check(object)) {
+ PyErr_Format(PyExc_TypeError, "Must be mapping, not %s",
+ object->ob_type->tp_name);
+ retval = 0;
+ break;
+ }
+
+ length = PyMapping_Length(object);
+ if (length < 0) {
+ retval = -1;
+ break;
+ }
+
+ keys = PyMapping_Keys(object);
+ if (keys == NULL) {
+ retval = -1;
+ break;
+ }
+
+ values = PyMapping_Values(object);
+ if (values == NULL) {
+ retval = -1;
+ Py_DECREF(keys);
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+
+ for (i = 0; i < length; i++) {
+ PyObject *key;
+ PyObject *value;
+
+ key = PyList_GET_ITEM(keys, i);
+ value = PyList_GET_ITEM(values, i);
+
+ retval = pygi_gi_type_info_check_py_object(key_type_info, key);
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ PyErr_PREFIX_FROM_FORMAT("Key %zd :", i);
+ break;
+ }
+
+ retval = pygi_gi_type_info_check_py_object(value_type_info, value);
+ if (retval < 0) {
+ break;
+ }
+ if (!retval) {
+ PyErr_PREFIX_FROM_FORMAT("Value %zd :", i);
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ Py_DECREF(values);
+ Py_DECREF(keys);
+ break;
+ }
case GI_TYPE_TAG_GTYPE:
{
gint is_instance;
@@ -429,7 +499,6 @@ check_number_clean:
break;
}
case GI_TYPE_TAG_TIME_T:
- case GI_TYPE_TAG_GHASH:
case GI_TYPE_TAG_ERROR:
/* TODO */
default:
@@ -782,6 +851,103 @@ array_clean:
break;
}
+ case GI_TYPE_TAG_GHASH:
+ {
+ Py_ssize_t length;
+ PyObject *keys;
+ PyObject *values;
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GITypeTag key_type_tag;
+ GHashFunc hash_func;
+ GEqualFunc equal_func;
+ GHashTable *hash_table;
+ Py_ssize_t i;
+
+ length = PyMapping_Length(object);
+ if (length < 0) {
+ break;
+ }
+
+ keys = PyMapping_Keys(object);
+ if (keys == NULL) {
+ break;
+ }
+
+ values = PyMapping_Values(object);
+ if (values == NULL) {
+ Py_DECREF(keys);
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+
+ key_type_tag = g_type_info_get_tag(key_type_info);
+
+ switch(key_type_tag) {
+ case GI_TYPE_TAG_UTF8:
+ case GI_TYPE_TAG_FILENAME:
+ hash_func = g_str_hash;
+ equal_func = g_str_equal;
+ break;
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_INT8:
+ case GI_TYPE_TAG_UINT8:
+ case GI_TYPE_TAG_INT16:
+ case GI_TYPE_TAG_UINT16:
+ case GI_TYPE_TAG_INT32:
+ hash_func = g_int_hash;
+ equal_func = g_int_equal;
+ break;
+ default:
+ PyErr_WarnEx(NULL, "No suited hash function available; using pointers", 1);
+ hash_func = g_direct_hash;
+ equal_func = g_direct_equal;
+ }
+
+ hash_table = g_hash_table_new(hash_func, equal_func);
+ if (hash_table == NULL) {
+ PyErr_NoMemory();
+ Py_DECREF(keys);
+ Py_DECREF(values);
+ break;
+ }
+
+ for (i = 0; i < length; i++) {
+ PyObject *py_key;
+ PyObject *py_value;
+ GArgument key;
+ GArgument value;
+
+ py_key = PyList_GET_ITEM(keys, i);
+ py_value = PyList_GET_ITEM(values, i);
+
+ key = pygi_g_argument_from_py_object(py_key, key_type_info);
+ if (PyErr_Occurred()) {
+ /* TODO: free the previous items */
+ break;
+ }
+
+ value = pygi_g_argument_from_py_object(py_value, value_type_info);
+ if (PyErr_Occurred()) {
+ /* TODO: free the previous items */
+ break;
+ }
+
+ g_hash_table_insert(hash_table, key.v_pointer, value.v_pointer);
+ }
+
+ arg.v_pointer = hash_table;
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ Py_DECREF(keys);
+ Py_DECREF(values);
+ break;
+ }
case GI_TYPE_TAG_ERROR:
/* Allow NULL GError, otherwise fall through */
if (object == Py_None) {
@@ -1061,6 +1227,55 @@ struct_error_clean:
g_base_info_unref((GIBaseInfo *)item_type_info);
break;
}
+ case GI_TYPE_TAG_GHASH:
+ {
+ GITypeInfo *key_type_info;
+ GITypeInfo *value_type_info;
+ GHashTableIter hash_table_iter;
+ GArgument key;
+ GArgument value;
+
+ object = PyDict_New();
+ if (object == NULL) {
+ break;
+ }
+
+ key_type_info = g_type_info_get_param_type(type_info, 0);
+ value_type_info = g_type_info_get_param_type(type_info, 1);
+
+ g_hash_table_iter_init(&hash_table_iter, (GHashTable *)arg.v_pointer);
+ while (g_hash_table_iter_next(&hash_table_iter, &key.v_pointer, &value.v_pointer)) {
+ PyObject *py_key;
+ PyObject *py_value;
+ int retval;
+
+ py_key = pygi_g_argument_to_py_object(key, key_type_info);
+ if (py_key == NULL) {
+ break;
+ }
+
+ py_value = pygi_g_argument_to_py_object(value, value_type_info);
+ if (py_value == NULL) {
+ Py_DECREF(py_key);
+ break;
+ }
+
+ retval = PyDict_SetItem(object, py_key, py_value);
+
+ Py_DECREF(py_key);
+ Py_DECREF(py_value);
+
+ if (retval < 0) {
+ Py_DECREF(object);
+ object = NULL;
+ break;
+ }
+ }
+
+ g_base_info_unref((GIBaseInfo *)key_type_info);
+ g_base_info_unref((GIBaseInfo *)value_type_info);
+ break;
+ }
case GI_TYPE_TAG_GTYPE:
{
object = pyg_type_wrapper_new(arg.v_long);
diff --git a/tests/test_girepository.py b/tests/test_girepository.py
index 97faed3..8e8c6a7 100644
--- a/tests/test_girepository.py
+++ b/tests/test_girepository.py
@@ -27,6 +27,7 @@ utf8_const = 'const \xe2\x99\xa5 utf8'
utf8_nonconst = 'nonconst \xe2\x99\xa5 utf8'
test_sequence = ('1', '2', '3')
+test_dict = {'foo': 'bar', 'baz': 'bat', 'qux': 'quux'}
def createStructA():
a = Everything.TestStructA()
@@ -409,6 +410,20 @@ class TestGIEverything(unittest.TestCase):
self.assertRaises(TypeError, Everything.test_gslist_nothing_in, (1, 2, 3))
+# GHashTable
+
+ def testGHashTableReturn(self):
+ self.assertEqual(test_dict, Everything.test_ghash_everything_return())
+
+ def testGHashTableIn(self):
+ Everything.test_ghash_nothing_in(test_dict)
+
+ # Test type checking.
+ self.assertRaises(TypeError, Everything.test_ghash_nothing_in, 'foo')
+ self.assertRaises(TypeError, Everything.test_ghash_nothing_in, {'foo': 42})
+ self.assertRaises(TypeError, Everything.test_ghash_nothing_in, {42: 'foo'})
+
+
# closure
def testClosure(self):
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]