[pygobject/gsoc2009: 45/160] Refactore pygi_g_argument_from_py_object
- From: Simon van der Linden <svdlinden src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pygobject/gsoc2009: 45/160] Refactore pygi_g_argument_from_py_object
- Date: Fri, 14 Aug 2009 21:25:52 +0000 (UTC)
commit 23f11a80329b0d7fc4a4df3c2678a91151628763
Author: Simon van der Linden <svdlinden src gnome org>
Date: Mon Jul 20 17:58:49 2009 +0200
Refactore pygi_g_argument_from_py_object
gi/pygargument.c | 307 ++++++++++++++++++++++++++++++------------------------
gi/pygargument.h | 5 +-
gi/pygiinfo.c | 14 ++-
3 files changed, 186 insertions(+), 140 deletions(-)
---
diff --git a/gi/pygargument.c b/gi/pygargument.c
index aab413a..bd27313 100644
--- a/gi/pygargument.c
+++ b/gi/pygargument.c
@@ -393,160 +393,197 @@ check_number_clean:
}
GArgument
-pyg_argument_from_pyobject(PyObject *object, GITypeInfo *type_info)
+pygi_g_argument_from_py_object(PyObject *object, GITypeInfo *type_info)
{
GArgument arg;
- GITypeTag type_tag;
- type_tag = g_type_info_get_tag((GITypeInfo*)type_info);
- switch (type_tag) {
- case GI_TYPE_TAG_VOID:
- /* Nothing to do */
- break;
- case GI_TYPE_TAG_UTF8:
- if (object == Py_None)
- arg.v_pointer = NULL;
- else
- arg.v_pointer = g_strdup(PyString_AsString(object));
- break;
- case GI_TYPE_TAG_USHORT:
- arg.v_ushort = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_UINT8:
- arg.v_uint8 = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_UINT:
- arg.v_uint = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_UINT16:
- arg.v_uint16 = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_UINT32:
- arg.v_uint32 = PyLong_AsLongLong(object);
- break;
- case GI_TYPE_TAG_UINT64:
- if (PyInt_Check(object)) {
- PyObject *long_obj = PyNumber_Long(object);
- arg.v_uint64 = PyLong_AsUnsignedLongLong(long_obj);
- Py_DECREF(long_obj);
- } else
- arg.v_uint64 = PyLong_AsUnsignedLongLong(object);
- break;
- case GI_TYPE_TAG_SHORT:
- arg.v_short = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_INT8:
- arg.v_int8 = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_INT:
- arg.v_int = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_SSIZE:
- case GI_TYPE_TAG_LONG:
- arg.v_long = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_SIZE:
- case GI_TYPE_TAG_ULONG:
- arg.v_ulong = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_BOOLEAN:
- arg.v_boolean = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_INT16:
- arg.v_int16 = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_INT32:
- arg.v_int32 = PyInt_AsLong(object);
- break;
- case GI_TYPE_TAG_INT64:
- arg.v_int64 = PyLong_AsLongLong(object);
- break;
- case GI_TYPE_TAG_FLOAT:
- arg.v_float = (float)PyFloat_AsDouble(object);
- break;
- case GI_TYPE_TAG_DOUBLE:
- arg.v_double = PyFloat_AsDouble(object);
- break;
- case GI_TYPE_TAG_INTERFACE:
+ switch (g_type_info_get_tag(type_info))
{
- GIBaseInfo* interface_info;
- GIInfoType interface_info_type;
+ case GI_TYPE_TAG_VOID:
+ /* Nothing to do */
+ break;
+ case GI_TYPE_TAG_BOOLEAN:
+ arg.v_boolean = PyObject_IsTrue(object);
+ break;
+ case GI_TYPE_TAG_SHORT:
+ case GI_TYPE_TAG_USHORT:
+ 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:
+ case GI_TYPE_TAG_INT:
+ case GI_TYPE_TAG_SSIZE:
+ case GI_TYPE_TAG_LONG:
+ {
+ PyObject *int_;
+ int_ = PyNumber_Int(object);
+ if (int_ == NULL) {
+ break;
+ }
+ arg.v_long = PyInt_AsLong(int_);
+ Py_DECREF(int_);
+ break;
+ }
+ case GI_TYPE_TAG_UINT32:
+ case GI_TYPE_TAG_UINT64:
+ case GI_TYPE_TAG_UINT:
+ case GI_TYPE_TAG_SIZE:
+ case GI_TYPE_TAG_ULONG:
+ {
+ PyObject *long_;
+ long_ = PyNumber_Long(object);
+ if (long_ == NULL) {
+ break;
+ }
+ arg.v_uint64 = PyLong_AsUnsignedLongLong(long_);
+ Py_DECREF(long_);
+ break;
+ }
+ case GI_TYPE_TAG_INT64:
+ {
+ PyObject *long_;
+ long_ = PyNumber_Long(object);
+ if (long_ == NULL) {
+ break;
+ }
+ arg.v_int64 = PyLong_AsLongLong(long_);
+ Py_DECREF(long_);
+ break;
+ }
+ case GI_TYPE_TAG_FLOAT:
+ {
+ PyObject *float_;
+ float_ = PyNumber_Float(object);
+ if (float_ == NULL) {
+ break;
+ }
+ arg.v_float = (float)PyFloat_AsDouble(float_);
+ Py_DECREF(float_);
+ break;
+ }
+ case GI_TYPE_TAG_DOUBLE:
+ {
+ PyObject *float_;
+ float_ = PyNumber_Float(object);
+ if (float_ == NULL) {
+ break;
+ }
+ arg.v_double = PyFloat_AsDouble(float_);
+ Py_DECREF(float_);
+ break;
+ }
+ case GI_TYPE_TAG_UTF8:
+ arg.v_string = g_strdup(PyString_AsString(object));
+ break;
+ case GI_TYPE_TAG_INTERFACE:
+ {
+ GIBaseInfo *info;
- interface_info = g_type_info_get_interface(type_info);
- interface_info_type = g_base_info_get_type(interface_info);
+ info = g_type_info_get_interface(type_info);
- switch (interface_info_type) {
- case GI_INFO_TYPE_ENUM:
- arg.v_int = PyInt_AsLong(object);
- break;
- case GI_INFO_TYPE_STRUCT:
- {
- GType gtype;
- PyObject *py_buffer;
+ switch (g_base_info_get_type(info)) {
+ case GI_INFO_TYPE_ENUM:
+ {
+ PyObject *int_;
+ int_ = PyNumber_Int(object);
+ if (int_ == NULL) {
+ break;
+ }
+ arg.v_long = PyInt_AsLong(int_);
+ Py_DECREF(int_);
+ break;
+ }
+ case GI_INFO_TYPE_STRUCT:
+ {
+ GType type;
+ gsize size;
+ gpointer buffer;
- gtype = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)interface_info);
+ type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
- if (g_type_is_a(gtype, G_TYPE_VALUE)) {
- GValue *value;
- int retval;
- PyObject *py_type;
+ /* Handle special cases first. */
+ if (g_type_is_a(type, G_TYPE_VALUE)) {
+ GValue *value;
+ GType object_type;
+ gint retval;
+
+ object_type = pyg_type_from_object(object->ob_type);
+ if (object_type == G_TYPE_INVALID) {
+ PyErr_SetString(PyExc_RuntimeError, "Unable to retrieve object's GType");
+ break;
+ }
- value = g_slice_new0(GValue);
+ value = g_slice_new0(GValue);
+ g_value_init(value, object_type);
- py_type = PyObject_Type(object);
- g_assert(py_type != NULL);
+ retval = pyg_value_from_pyobject(value, object);
+ if (retval < 0) {
+ g_slice_free(GValue, value);
+ PyErr_SetString(PyExc_RuntimeError, "PyObject conversion to GValue failed");
+ break;
+ }
- g_value_init(value, pyg_type_from_object(py_type));
+ arg.v_pointer = value;
+ break;
+ } else if (g_type_is_a(type, G_TYPE_CLOSURE)) {
+ GClosure *closure;
- retval = pyg_value_from_pyobject(value, object);
- g_assert(retval == 0);
+ closure = pyg_closure_new(object, NULL, NULL);
+ if (closure == NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "GClosure creation failed");
+ break;
+ }
- arg.v_pointer = value;
- break;
- } else if (g_type_is_a(gtype, G_TYPE_CLOSURE)) {
- arg.v_pointer = pyg_closure_new(object, NULL, NULL);
- break;
- }
+ arg.v_pointer = closure;
+ break;
+ }
- py_buffer = PyObject_GetAttrString(object, "__buffer__");
- g_assert(py_buffer != NULL);
- (*py_buffer->ob_type->tp_as_buffer->bf_getreadbuffer)(py_buffer, 0, &arg.v_pointer);
+ buffer = pygi_py_object_get_buffer(object, &size);
- break;
- }
- case GI_INFO_TYPE_OBJECT:
- if (object == Py_None) {
- arg.v_pointer = NULL;
+ arg.v_pointer = buffer;
break;
}
- arg.v_pointer = pygobject_get(object);
- break;
- default:
- /* TODO: To complete with other types. */
- g_assert_not_reached();
+ case GI_INFO_TYPE_OBJECT:
+ arg.v_pointer = pygobject_get(object);
+ break;
+ default:
+ /* TODO */
+ g_assert_not_reached();
+ }
+ g_base_info_unref(info);
+ break;
}
- g_base_info_unref((GIBaseInfo *)interface_info);
- break;
- }
- case GI_TYPE_TAG_ARRAY:
- {
- gsize length;
- arg.v_pointer = pyg_array_from_pyobject(object, type_info, &length);
- break;
- }
- case GI_TYPE_TAG_ERROR:
- /* Allow NULL GError, otherwise fall through */
- if (object == Py_None) {
- arg.v_pointer = NULL;
+ case GI_TYPE_TAG_ARRAY:
+ {
+ gsize length;
+ arg.v_pointer = pyg_array_from_pyobject(object, type_info, &length);
break;
}
- case GI_TYPE_TAG_GTYPE:
- arg.v_int = pyg_type_from_object(object);
- break;
- default:
- g_print("<PyO->GArg> GITypeTag %s is unhandled\n",
- g_type_tag_to_string(type_tag));
- break;
+ case GI_TYPE_TAG_ERROR:
+ /* Allow NULL GError, otherwise fall through */
+ if (object == Py_None) {
+ arg.v_pointer = NULL;
+ break;
+ }
+ /* TODO */
+ g_assert_not_reached();
+ break;
+ case GI_TYPE_TAG_GTYPE:
+ {
+ GType type;
+
+ type = pyg_type_from_object(object);
+ if (type == G_TYPE_INVALID) {
+ PyErr_SetString(PyExc_RuntimeError, "GType conversion failed");
+ }
+
+ arg.v_long = type;
+ break;
+ }
+ default:
+ /* TODO */
+ g_assert_not_reached();
}
return arg;
@@ -693,7 +730,7 @@ pyg_array_from_pyobject(PyObject *object, GITypeInfo *type_info, gsize *length)
py_item = PyTuple_GetItem(object, i);
g_assert(py_item != NULL);
- arg = pyg_argument_from_pyobject(py_item, item_type_info);
+ arg = pygi_g_argument_from_py_object(py_item, item_type_info);
g_memmove(current_item, &arg, item_size);
diff --git a/gi/pygargument.h b/gi/pygargument.h
index d55a606..580ab16 100644
--- a/gi/pygargument.h
+++ b/gi/pygargument.h
@@ -31,8 +31,9 @@ G_BEGIN_DECLS
gint pygi_gi_type_info_check_py_object(GITypeInfo *type_info,
PyObject *object);
-GArgument pyg_argument_from_pyobject(PyObject *object,
- GITypeInfo *info);
+GArgument pygi_g_argument_from_py_object(PyObject *object,
+ GITypeInfo *type_info);
+
PyObject* pyg_argument_to_pyobject(GArgument *arg,
GITypeInfo *info);
diff --git a/gi/pygiinfo.c b/gi/pygiinfo.c
index 3f393c1..10c8f57 100644
--- a/gi/pygiinfo.c
+++ b/gi/pygiinfo.c
@@ -552,7 +552,7 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
container_info = g_base_info_get_container(self->info);
container_info_type = g_base_info_get_type(container_info);
- /* FIXME: this could take place in pyg_argument_from_pyobject, but we need to create an
+ /* FIXME: this could take place in pygi_g_argument_from_py_object, but we need to create an
independant function because it needs a GITypeInfo to be passed. */
switch(container_info_type) {
@@ -799,7 +799,15 @@ _wrap_g_function_info_invoke(PyGIBaseInfo *self, PyObject *args)
py_arg = PyTuple_GetItem(args, py_args_pos);
g_assert(py_arg != NULL);
- GArgument in_value = pyg_argument_from_pyobject(py_arg, g_arg_info_get_type(arg_info));
+ GArgument in_value = pygi_g_argument_from_py_object(py_arg, g_arg_info_get_type(arg_info));
+
+ if (PyErr_Occurred()) {
+ /* TODO: Release ressources allocated for previous arguments. */
+ g_base_info_unref((GIBaseInfo *)arg_type_info);
+ g_base_info_unref((GIBaseInfo *)arg_info);
+ g_base_info_unref((GIBaseInfo *)return_info);
+ return NULL;
+ }
if (direction == GI_DIRECTION_IN) {
/* Pass the value. */
@@ -1591,7 +1599,7 @@ _wrap_g_field_info_set_value(PyGIBaseInfo *self, PyObject *args)
goto return_;
}
- value = pyg_argument_from_pyobject(py_value, field_type_info);
+ value = pygi_g_argument_from_py_object(py_value, field_type_info);
/* A few types are not handled by g_field_info_set_field, so do it here. */
if (!g_type_info_is_pointer(field_type_info)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]