[pygobject/gsoc2009: 17/160] Add type checking in FieldInfo.set_value
- From: Simon van der Linden <svdlinden src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pygobject/gsoc2009: 17/160] Add type checking in FieldInfo.set_value
- Date: Fri, 14 Aug 2009 21:23:31 +0000 (UTC)
commit f825e71e6a1bcf9f0b31f6d44ae7e406941eee63
Author: Simon van der Linden <simon vanderlinden student uclouvain be>
Date: Sat Jun 27 15:33:33 2009 +0200
Add type checking in FieldInfo.set_value
Add type checking in _wrap_g_field_info_set_value and structure type
checking in pyg_argument_from_pyobject_check.
Return a GType wrapper instead of an integer in
_wrap_g_registered_type_info_get_g_type.
Correct GType lookup for structures and boxed values in
DynamicModule._create_boxed.
girepository/bank-argument.c | 18 ++++++++++++++++--
girepository/bank-info.c | 35 +++++++++++++++++++++++++++++++++--
girepository/module.py | 13 +++++++++----
3 files changed, 58 insertions(+), 8 deletions(-)
---
diff --git a/girepository/bank-argument.c b/girepository/bank-argument.c
index 75538c4..9f4d058 100644
--- a/girepository/bank-argument.c
+++ b/girepository/bank-argument.c
@@ -265,12 +265,22 @@ pyg_argument_from_pyobject_check(PyObject *object, GITypeInfo *type_info, GError
(void) PyInt_AsLong(object);
if (PyErr_Occurred()) {
PyErr_Clear();
+ g_base_info_unref(interface_info);
py_type_name_expected = "int";
goto check_error_type;
}
/* XXX: What if the value doesn't correspond to any enum field? */
- } else {
- /* TODO */
+ } else if (interface_info_type == GI_INFO_TYPE_STRUCT || interface_info_type == GI_INFO_TYPE_BOXED) {
+ GType gtype;
+ GType object_gtype;
+
+ gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)interface_info);
+ object_gtype = pyg_type_from_object(object);
+ if (object_gtype != gtype) {
+ g_base_info_unref(interface_info);
+ py_type_name_expected = g_type_name(gtype);
+ goto check_error_type;
+ }
}
g_base_info_unref(interface_info);
@@ -304,7 +314,11 @@ pyg_argument_from_pyobject_check(PyObject *object, GITypeInfo *type_info, GError
check_error_type:
{
PyObject *py_type;
+
py_type = PyObject_Type(object);
+
+ g_assert(py_type_name_expected != NULL);
+
g_set_error(error, PyG_ARGUMENT_FROM_PYOBJECT_ERROR, PyG_ARGUMENT_FROM_PYOBJECT_ERROR_TYPE,
"Must be %s, not %s", py_type_name_expected, ((PyTypeObject *)py_type)->tp_name);
Py_XDECREF(py_type);
diff --git a/girepository/bank-info.c b/girepository/bank-info.c
index ca09f52..652b1f8 100644
--- a/girepository/bank-info.c
+++ b/girepository/bank-info.c
@@ -602,17 +602,22 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
/* FIXME: We should reuse this. Perhaps by separating the
* wrapper creation from the binding to the wrapper.
*/
+ GIStructInfo *struct_info;
gsize size;
PyObject *buffer;
int retval;
- size = g_struct_info_get_size ((GIStructInfo *)return_info);
+ struct_info = g_interface_info_get_iface_struct((GIInterfaceInfo *)interface_info);
+
+ size = g_struct_info_get_size (struct_info);
g_assert(size > 0);
buffer = PyBuffer_FromReadWriteMemory(return_arg.v_pointer, size);
retval = PyObject_SetAttrString(return_value, "__buffer__", buffer);
g_assert(retval != -1);
+
+ g_base_info_unref((GIBaseInfo *)struct_info);
} else {
PyGObject *gobject;
@@ -798,7 +803,7 @@ _wrap_g_registered_type_info_get_g_type (PyGIBaseInfo* self)
int gtype;
gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo*)self->info);
- return PyInt_FromLong(gtype);
+ return pyg_type_wrapper_new(gtype);
}
static PyMethodDef _PyGIRegisteredTypeInfo_methods[] = {
@@ -1272,6 +1277,7 @@ _wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
GIInfoType container_type;
GITypeInfo *field_type_info;
PyObject *retval;
+ GError *error;
retval = Py_None;
@@ -1308,6 +1314,31 @@ _wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
buffer = ((PyGObject *) obj)->obj;
}
+ /* Check the value. */
+ error = NULL;
+ if (!pyg_argument_from_pyobject_check(value, field_type_info, &error)) {
+ PyObject *py_error_type;
+ switch(error->code) {
+ case PyG_ARGUMENT_FROM_PYOBJECT_ERROR_TYPE:
+ py_error_type = PyExc_TypeError;
+ break;
+ case PyG_ARGUMENT_FROM_PYOBJECT_ERROR_VALUE:
+ py_error_type = PyExc_ValueError;
+ break;
+ default:
+ g_assert_not_reached();
+ py_error_type = NULL;
+ }
+
+ PyErr_Format(py_error_type, "%s.set_value() argument 1: %s",
+ g_base_info_get_namespace((GIBaseInfo *)self->info), error->message);
+
+ g_clear_error(&error);
+
+ retval = NULL;
+ goto field_info_set_value_return;
+ }
+
arg = pyg_argument_from_pyobject(value, field_type_info);
/* A few types are not handled by g_field_info_set_field, so do it here. */
diff --git a/girepository/module.py b/girepository/module.py
index d05c9c0..6b6b875 100644
--- a/girepository/module.py
+++ b/girepository/module.py
@@ -194,7 +194,7 @@ class DynamicModule(object):
namespace = repository.get_c_prefix(boxed_info.getNamespace())
full_name = namespace + name
- boxed_info.getGType()
+
gtype = None
try:
gtype = gobject.GType.from_name(full_name)
@@ -203,6 +203,7 @@ class DynamicModule(object):
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.
@@ -215,9 +216,13 @@ class DynamicModule(object):
bases += gobject.Boxed
klass = buildType(boxed_info, bases)
- if gtype is not None:
- klass.__gtype__ = gtype
- gtype.pytype = klass
+
+ if gtype is None:
+ gtype = boxed_info.getGType()
+
+ klass.__gtype__ = gtype
+ gtype.pytype = klass
+
self.__dict__[name] = klass
return klass
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]