[pygobject] Unify Python interface struct to GI marshaling code
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Unify Python interface struct to GI marshaling code
- Date: Fri, 5 Apr 2013 12:54:39 +0000 (UTC)
commit 6d3a0751e71ee3c37b3bb646723aed75971e5b39
Author: Simon Feltman <sfeltman src gnome org>
Date: Thu Mar 28 22:41:51 2013 -0700
Unify Python interface struct to GI marshaling code
Add pygi_marshal_from_py_interface_struct used for direct gi method
call in args and vfunc out args.
https://bugzilla.gnome.org/show_bug.cgi?id=693405
gi/pygi-argument.c | 75 +++++++-------------
gi/pygi-cache.c | 12 +---
gi/pygi-marshal-from-py.c | 167 ++++++++++++++++++++++++++++-----------------
gi/pygi-marshal-from-py.h | 11 +++
4 files changed, 141 insertions(+), 124 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 8cc467c..9540f5a 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1143,56 +1143,31 @@ array_success:
case GI_INFO_TYPE_STRUCT:
case GI_INFO_TYPE_UNION:
{
- GType type;
-
- if (object == Py_None) {
- arg.v_pointer = NULL;
- break;
- }
-
- type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
-
- /* Handle special cases first. */
- if (g_type_is_a (type, G_TYPE_VALUE)) {
- g_warn_if_fail (transfer == GI_TRANSFER_NOTHING);
- /* This will currently leak the GValue that is allocated and
- * stashed in arg.v_pointer. Out argument marshaling for caller
- * allocated GValues already pass in memory for the GValue.
- * Further re-factoring is needed to fix this leak.
- * See: https://bugzilla.gnome.org/show_bug.cgi?id=693405
- */
- pygi_marshal_from_py_gvalue (object,
- &arg,
- transfer,
- FALSE /*is_allocated*/);
-
- } else if (g_type_is_a (type, G_TYPE_CLOSURE)) {
- pygi_marshal_from_py_gclosure (object, &arg);
- } else if (g_struct_info_is_foreign (info)) {
- pygi_struct_foreign_convert_to_g_argument (object, info, transfer, &arg);
- } else if (g_type_is_a (type, G_TYPE_BOXED)) {
- if (pyg_boxed_check (object, type)) {
- arg.v_pointer = pyg_boxed_get (object, void);
- if (transfer == GI_TRANSFER_EVERYTHING) {
- arg.v_pointer = g_boxed_copy (type, arg.v_pointer);
- }
- } else {
- PyErr_Format (PyExc_TypeError, "wrong boxed type");
- }
- } else if (g_type_is_a (type, G_TYPE_POINTER) ||
- g_type_is_a (type, G_TYPE_VARIANT) ||
- type == G_TYPE_NONE) {
- g_warn_if_fail (g_type_is_a (type, G_TYPE_VARIANT) || !g_type_info_is_pointer
(type_info) || transfer == GI_TRANSFER_NOTHING);
-
- if (g_type_is_a (type, G_TYPE_VARIANT) && pyg_type_from_object (object) !=
G_TYPE_VARIANT) {
- PyErr_SetString (PyExc_TypeError, "expected GLib.Variant");
- break;
- }
- arg.v_pointer = pyg_pointer_get (object, void);
- } else {
- PyErr_Format (PyExc_NotImplementedError, "structure type '%s' is not supported yet",
g_type_name (type));
- }
-
+ GType g_type;
+ PyObject *py_type;
+
+ g_type = g_registered_type_info_get_g_type ( (GIRegisteredTypeInfo *) info);
+ py_type = _pygi_type_import_by_gi_info ( (GIBaseInfo *) info);
+
+ /* Note for G_TYPE_VALUE g_type:
+ * This will currently leak the GValue that is allocated and
+ * stashed in arg.v_pointer. Out argument marshaling for caller
+ * allocated GValues already pass in memory for the GValue.
+ * Further re-factoring is needed to fix this leak.
+ * See: https://bugzilla.gnome.org/show_bug.cgi?id=693405
+ */
+ pygi_marshal_from_py_interface_struct (object,
+ &arg,
+ NULL, /*arg_name*/
+ info, /*interface_info*/
+ type_info,
+ g_type,
+ py_type,
+ transfer,
+ FALSE, /*is_caller_allocates*/
+ g_struct_info_is_foreign (info));
+
+ Py_DECREF (py_type);
break;
}
case GI_INFO_TYPE_ENUM:
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 99f49cf..d149732 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -756,6 +756,7 @@ _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
_arg_cache_to_py_interface_union_setup (arg_cache, transfer);
break;
+ case GI_INFO_TYPE_BOXED:
case GI_INFO_TYPE_STRUCT:
if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
_arg_cache_from_py_interface_struct_setup (arg_cache,
@@ -776,17 +777,6 @@ _arg_cache_new_for_interface (GIInterfaceInfo *iface_info,
_arg_cache_to_py_interface_object_setup (arg_cache, transfer);
break;
- case GI_INFO_TYPE_BOXED:
- if (direction == PYGI_DIRECTION_FROM_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
- _arg_cache_from_py_interface_struct_setup (arg_cache,
- iface_info,
- transfer);
-
- if (direction == PYGI_DIRECTION_TO_PYTHON || direction == PYGI_DIRECTION_BIDIRECTIONAL)
- _arg_cache_to_py_interface_struct_setup (arg_cache,
- iface_info,
- transfer);
- break;
case GI_INFO_TYPE_CALLBACK:
{
PyGICallbackCache *callback_cache;
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index 5858e68..639a226 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -194,19 +194,19 @@ gi_argument_from_c_long (GIArgument *arg_out,
* expected C union
*/
static gboolean
-_is_union_member (PyGIInterfaceCache *iface_cache, PyObject *py_arg) {
+_is_union_member (GIInterfaceInfo *interface_info, PyObject *py_arg) {
gint i;
gint n_fields;
GIUnionInfo *union_info;
GIInfoType info_type;
gboolean is_member = FALSE;
- info_type = g_base_info_get_type (iface_cache->interface_info);
+ info_type = g_base_info_get_type (interface_info);
if (info_type != GI_INFO_TYPE_UNION)
return FALSE;
- union_info = (GIUnionInfo *) iface_cache->interface_info;
+ union_info = (GIUnionInfo *) interface_info;
n_fields = g_union_info_get_n_fields (union_info);
for (i = 0; i < n_fields; i++) {
@@ -1643,65 +1643,16 @@ _pygi_marshal_from_py_interface_struct (PyGIInvokeState *state,
{
PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
- if (py_arg == Py_None) {
- arg->v_pointer = NULL;
- return TRUE;
- }
-
- /* FIXME: handle this large if statement in the cache
- * and set the correct marshaller
- */
-
- if (iface_cache->g_type == G_TYPE_CLOSURE) {
- return pygi_marshal_from_py_gclosure (py_arg, arg);
- } else if (iface_cache->g_type == G_TYPE_VALUE) {
- return pygi_marshal_from_py_gvalue(py_arg, arg,
- arg_cache->transfer,
- arg_cache->is_caller_allocates);
- } else if (iface_cache->is_foreign) {
- PyObject *success;
- success = pygi_struct_foreign_convert_to_g_argument (py_arg,
- iface_cache->interface_info,
- arg_cache->transfer,
- arg);
-
- return (success == Py_None);
- } else if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
- /* first check to see if this is a member of the expected union */
- if (!_is_union_member (iface_cache, py_arg)) {
- if (!PyErr_Occurred()) {
- PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
-
- PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
- arg_cache->arg_name ? arg_cache->arg_name : "self",
- iface_cache->type_name,
- module ? PYGLIB_PyUnicode_AsString(module) : "",
- module ? "." : "",
- py_arg->ob_type->tp_name);
- if (module)
- Py_DECREF (module);
- }
-
- return FALSE;
- }
- }
-
- if (g_type_is_a (iface_cache->g_type, G_TYPE_BOXED)) {
- arg->v_pointer = pyg_boxed_get (py_arg, void);
- if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
- arg->v_pointer = g_boxed_copy (iface_cache->g_type, arg->v_pointer);
- }
- } else if (g_type_is_a (iface_cache->g_type, G_TYPE_POINTER) ||
- g_type_is_a (iface_cache->g_type, G_TYPE_VARIANT) ||
- iface_cache->g_type == G_TYPE_NONE) {
- arg->v_pointer = pyg_pointer_get (py_arg, void);
- } else {
- PyErr_Format (PyExc_NotImplementedError,
- "structure type '%s' is not supported yet",
- g_type_name(iface_cache->g_type));
- return FALSE;
- }
- return TRUE;
+ return pygi_marshal_from_py_interface_struct (py_arg,
+ arg,
+ arg_cache->arg_name,
+ iface_cache->interface_info,
+ arg_cache->type_info,
+ iface_cache->g_type,
+ iface_cache->py_type,
+ arg_cache->transfer,
+ arg_cache->is_caller_allocates,
+ iface_cache->is_foreign);
}
gboolean
@@ -1775,7 +1726,7 @@ gboolean _pygi_marshal_from_py_interface_instance (PyGIInvokeState *state,
if (!PyObject_IsInstance (py_arg, iface_cache->py_type)) {
/* wait, we might be a member of a union so manually check */
- if (!_is_union_member (iface_cache, py_arg)) {
+ if (!_is_union_member (iface_cache->interface_info, py_arg)) {
if (!PyErr_Occurred()) {
PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
PyErr_Format (PyExc_TypeError,
@@ -1979,3 +1930,93 @@ pygi_marshal_from_py_gclosure(PyObject *py_arg,
arg->v_pointer = closure;
return TRUE;
}
+
+gboolean
+pygi_marshal_from_py_interface_struct (PyObject *py_arg,
+ GIArgument *arg,
+ const gchar *arg_name,
+ GIBaseInfo *interface_info,
+ GITypeInfo *type_info,
+ GType g_type,
+ PyObject *py_type,
+ GITransfer transfer,
+ gboolean is_allocated,
+ gboolean is_foreign)
+{
+ if (py_arg == Py_None) {
+ arg->v_pointer = NULL;
+ return TRUE;
+ }
+
+ /* FIXME: handle this large if statement in the cache
+ * and set the correct marshaller
+ */
+
+ if (g_type_is_a (g_type, G_TYPE_CLOSURE)) {
+ return pygi_marshal_from_py_gclosure (py_arg, arg);
+ } else if (g_type_is_a (g_type, G_TYPE_VALUE)) {
+ return pygi_marshal_from_py_gvalue(py_arg,
+ arg,
+ transfer,
+ is_allocated);
+ } else if (is_foreign) {
+ PyObject *success;
+ success = pygi_struct_foreign_convert_to_g_argument (py_arg,
+ interface_info,
+ transfer,
+ arg);
+
+ return (success == Py_None);
+ } else if (!PyObject_IsInstance (py_arg, py_type)) {
+ /* first check to see if this is a member of the expected union */
+ if (!_is_union_member (interface_info, py_arg)) {
+ if (!PyErr_Occurred()) {
+ gchar *type_name = _pygi_g_base_info_get_fullname (interface_info);
+ PyObject *module = PyObject_GetAttrString(py_arg, "__module__");
+
+ PyErr_Format (PyExc_TypeError, "argument %s: Expected %s, but got %s%s%s",
+ arg_name ? arg_name : "self",
+ type_name,
+ module ? PYGLIB_PyUnicode_AsString(module) : "",
+ module ? "." : "",
+ py_arg->ob_type->tp_name);
+ if (module)
+ Py_DECREF (module);
+ g_free (type_name);
+ }
+
+ return FALSE;
+ }
+ }
+
+ if (g_type_is_a (g_type, G_TYPE_BOXED)) {
+ if (pyg_boxed_check (py_arg, g_type)) {
+ arg->v_pointer = pyg_boxed_get (py_arg, void);
+ if (transfer == GI_TRANSFER_EVERYTHING) {
+ arg->v_pointer = g_boxed_copy (g_type, arg->v_pointer);
+ }
+ } else {
+ PyErr_Format (PyExc_TypeError, "wrong boxed type");
+ return FALSE;
+ }
+
+ } else if (g_type_is_a (g_type, G_TYPE_POINTER) ||
+ g_type_is_a (g_type, G_TYPE_VARIANT) ||
+ g_type == G_TYPE_NONE) {
+ g_warn_if_fail (g_type_is_a (g_type, G_TYPE_VARIANT) || !g_type_info_is_pointer (type_info) ||
transfer == GI_TRANSFER_NOTHING);
+
+ if (g_type_is_a (g_type, G_TYPE_VARIANT) &&
+ pyg_type_from_object (py_arg) != G_TYPE_VARIANT) {
+ PyErr_SetString (PyExc_TypeError, "expected GLib.Variant");
+ return FALSE;
+ }
+ arg->v_pointer = pyg_pointer_get (py_arg, void);
+
+ } else {
+ PyErr_Format (PyExc_NotImplementedError,
+ "structure type '%s' is not supported yet",
+ g_type_name(g_type));
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/gi/pygi-marshal-from-py.h b/gi/pygi-marshal-from-py.h
index e0a57d3..307d716 100644
--- a/gi/pygi-marshal-from-py.h
+++ b/gi/pygi-marshal-from-py.h
@@ -198,6 +198,17 @@ gboolean pygi_marshal_from_py_gvalue (PyObject *py_arg, /*in*/
gboolean pygi_marshal_from_py_gclosure(PyObject *py_arg, /*in*/
GIArgument *arg); /*out*/
+gboolean pygi_marshal_from_py_interface_struct (PyObject *py_arg,
+ GIArgument *arg,
+ const gchar *arg_name,
+ GIBaseInfo *interface_info,
+ GITypeInfo *type_info,
+ GType g_type,
+ PyObject *py_type,
+ GITransfer transfer,
+ gboolean is_allocated,
+ gboolean is_foreign);
+
G_END_DECLS
#endif /* __PYGI_MARSHAL_from_py_PY__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]