[pygobject/invoke-rewrite] [gi] fix constructor invoking and add some support for interface out values



commit 1006df1929a667716c25e74b35b8f14643358732
Author: John (J5) Palmieri <johnp redhat com>
Date:   Tue Jan 18 11:24:06 2011 -0500

    [gi] fix constructor invoking and add some support for interface out values
    
    * constructors are now simplified and are treated like normal static methods
      which happen to return an instance

 gi/pygi-argument.c |    8 +--
 gi/pygi-cache.c    |  132 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 gi/pygi-invoke.c   |    9 ++--
 gi/types.py        |   21 ++------
 4 files changed, 142 insertions(+), 28 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 2c6d629..3a56023 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -2914,7 +2914,7 @@ _pygi_marshal_in_interface_callback (PyGIInvokeState   *state,
         }
     }
  
-    if (py_arg == Py_None && py_user_data != Py_None) {
+    if (py_arg == Py_None && !(py_user_data == Py_None || py_user_data == NULL)) {
         Py_DECREF(py_user_data);
         PyErr_Format(PyExc_TypeError,
                      "When passing None for a callback userdata must also be None");
@@ -3432,10 +3432,8 @@ _pygi_marshal_out_interface_object (PyGIInvokeState   *state,
                                     PyGIArgCache      *arg_cache,
                                     GIArgument        *arg)
 {
-    PyObject *py_obj = NULL;
-
-    PyErr_Format(PyExc_NotImplementedError,
-                 "Marshalling for this type is not implemented yet");
+    PyObject *py_obj = pygobject_new (arg->v_pointer);
+;
     return py_obj;
 }
 
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index af5f79b..c83d25b 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -797,7 +797,134 @@ _arg_cache_new_for_out_gerror(void)
     arg_cache->aux_type = PYGI_AUX_TYPE_IGNORE;
     return arg_cache;
 }
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_struct(GIInterfaceInfo *iface_info,
+                                        GITransfer transfer)
+{
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
+    PyGIInterfaceCache *iface_cache = _interface_cache_new_from_interface_info(iface_info);
+    PyGIArgCache *arg_cache = (PyGIArgCache *)iface_cache;
+    iface_cache->is_foreign = g_struct_info_is_foreign( (GIStructInfo*)iface_info);
+    arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
+    if (iface_cache->g_type == G_TYPE_VALUE)
+        arg_cache->cleanup = _g_slice_free_gvalue_func;
+    if (iface_cache->g_type == G_TYPE_CLOSURE)
+        arg_cache->cleanup = g_closure_unref;
+
+    return arg_cache;
+}
 
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_object(GIInterfaceInfo *iface_info,
+                                        GITransfer transfer)
+{
+    PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
+    arg_cache->out_marshaller = _pygi_marshal_out_interface_object;
+
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_boxed(GIInterfaceInfo *iface_info,
+                                      GITransfer transfer)
+{
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return FALSE;
+
+    PyGIArgCache *arg_cache = (PyGIArgCache *)_interface_cache_new_from_interface_info(iface_info);
+    arg_cache->in_marshaller = _pygi_marshal_in_interface_boxed;
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_callback(void)
+{
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Callback returns are not supported");
+    return FALSE;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_enum(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_enum;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_union(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_enum;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+static inline PyGIArgCache *
+_arg_cache_new_for_out_interface_flags(void)
+{
+    PyGIArgCache *arg_cache = NULL;
+    /*arg_cache->in_marshaller = _pygi_marshal_in_flags;*/
+    PyErr_Format(PyExc_NotImplementedError,
+                 "Caching for this type is not fully implemented yet");
+    return arg_cache;
+}
+
+PyGIArgCache *
+_arg_cache_out_new_from_interface_info (GIInterfaceInfo *iface_info,
+                                        PyGIFunctionCache *function_cache,
+                                        GIInfoType info_type,
+                                        GITransfer transfer,
+                                        GIDirection direction,
+                                        gint c_arg_index)
+{
+    PyGIArgCache *arg_cache = NULL;
+
+    switch (info_type) {
+        case GI_INFO_TYPE_UNION:
+            arg_cache = _arg_cache_new_for_out_interface_union();
+            break;
+        case GI_INFO_TYPE_STRUCT:
+            arg_cache = _arg_cache_new_for_out_interface_struct(iface_info,
+                                                               transfer);
+            break;
+        case GI_INFO_TYPE_OBJECT:
+        case GI_INFO_TYPE_INTERFACE:
+            arg_cache = _arg_cache_new_for_out_interface_object(iface_info,
+                                                                transfer);
+            break;
+        case GI_INFO_TYPE_BOXED:
+            arg_cache = _arg_cache_new_for_out_interface_boxed(iface_info,
+                                                               transfer);
+            break;
+        case GI_INFO_TYPE_CALLBACK:
+            arg_cache = _arg_cache_new_for_out_interface_callback();
+            break;
+        case GI_INFO_TYPE_ENUM:
+            arg_cache = _arg_cache_new_for_out_interface_enum();
+            break;
+        case GI_INFO_TYPE_FLAGS:
+            arg_cache = _arg_cache_new_for_out_interface_flags();
+            break;
+        default:
+            g_assert_not_reached();
+    }
+
+    if (arg_cache != NULL) {
+        arg_cache->direction = direction;
+        arg_cache->transfer = transfer;
+        arg_cache->type_tag = GI_TYPE_TAG_INTERFACE;
+        arg_cache->c_arg_index = c_arg_index;
+    }
+
+    return arg_cache;
+}
 
 PyGIArgCache *
 _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
@@ -863,7 +990,6 @@ _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
                                                    transfer);
            break;
        case GI_TYPE_TAG_INTERFACE:
-           /*
            {
                GIInterfaceInfo *interface_info = g_type_info_get_interface(type_info);
                GIInfoType info_type = g_base_info_get_type( (GIBaseInfo *) interface_info);
@@ -872,13 +998,11 @@ _arg_cache_out_new_from_type_info (GITypeInfo *type_info,
                                                                  info_type,
                                                                  transfer,
                                                                  direction,
-                                                                 c_arg_index,
-                                                                 py_arg_index);
+                                                                 c_arg_index);
 
                g_base_info_unref( (GIBaseInfo *) interface_info);
                return arg_cache;
            }
-           */
        case GI_TYPE_TAG_GLIST:
            arg_cache = _arg_cache_new_for_out_glist(type_info,
                                                    transfer);
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 349f6cd..b4359c1 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -1019,15 +1019,16 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
     int total_out_args = cache->n_out_args;
     gboolean has_return = FALSE;
 
-    if (cache->return_cache)
+    if (cache->return_cache) {
         py_return = cache->return_cache->out_marshaller(state,
                                                         cache,
                                                         cache->return_cache,
                                                         &state->return_arg);
 
-    if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
-        total_out_args++;
-        has_return = TRUE;
+        if (cache->return_cache->type_tag != GI_TYPE_TAG_VOID) {
+            total_out_args++;
+            has_return = TRUE;
+        }
     }
 
     if (cache->n_out_args == 0) {
diff --git a/gi/types.py b/gi/types.py
index cc43d02..08cbc22 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -51,7 +51,7 @@ def Constructor(info):
         cls_name = info.get_container().get_name()
         if cls.__name__ != cls_name:
             raise TypeError('%s constructor cannot be used to create instances of a subclass' % cls_name)
-        return info.invoke(cls, *args)
+        return info.invoke(*args)
 
     constructor.__info__ = info
     constructor.__name__ = info.get_name()
@@ -62,23 +62,16 @@ def Constructor(info):
 
 class MetaClassHelper(object):
 
-    def _setup_constructors(cls):
-        for method_info in cls.__info__.get_methods():
-            if method_info.is_constructor():
-                name = method_info.get_name()
-                constructor = classmethod(Constructor(method_info))
-                setattr(cls, name, constructor)
-
     def _setup_methods(cls):
         for method_info in cls.__info__.get_methods():
             name = method_info.get_name()
-            function = Function(method_info)
+
+            if method_info.is_constructor():
+                method = classmethod(Constructor(method_info))
             if method_info.is_method():
-                method = function
-            elif method_info.is_constructor():
-                continue
+                method = Function(method_info)
             else:
-                method = staticmethod(function)
+                method = staticmethod(Function(method_info))
             setattr(cls, name, method)
 
     def _setup_fields(cls):
@@ -170,7 +163,6 @@ class GObjectMeta(gobject.GObjectMeta, MetaClassHelper):
 
             if isinstance(cls.__info__, ObjectInfo):
                 cls._setup_fields()
-                cls._setup_constructors()
                 set_object_has_new_constructor(cls.__info__.get_g_type())
             elif isinstance(cls.__info__, InterfaceInfo):
                 register_interface_info(cls.__info__.get_g_type())
@@ -187,7 +179,6 @@ class StructMeta(type, MetaClassHelper):
 
         cls._setup_fields()
         cls._setup_methods()
-        cls._setup_constructors()
 
 class Enum(int):
     __info__ = None



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]