[pygobject/invoke-rewrite] [gi] remove the class parameter from the argument list of constructors



commit 482553ae5d863ca523be3bd1eededa5d02a4f87e
Author: John (J5) Palmieri <johnp redhat com>
Date:   Fri Mar 25 13:14:01 2011 -0400

    [gi] remove the class parameter from the argument list of constructors
    
     * constructors pass in their class to be constructed.  Since we use GI
       and g_object_new to do the construction we ignore this for now but
       keep it around in the state for future use.

 gi/pygi-invoke-ng.c           |   46 +++++++++++++++++++++++++++++++++++-----
 gi/pygi-invoke-state-struct.h |    1 +
 2 files changed, 41 insertions(+), 6 deletions(-)
---
diff --git a/gi/pygi-invoke-ng.c b/gi/pygi-invoke-ng.c
index 0275976..4dd01b2 100644
--- a/gi/pygi-invoke-ng.c
+++ b/gi/pygi-invoke-ng.c
@@ -2,6 +2,7 @@
  * vim: tabstop=4 shiftwidth=4 expandtab
  *
  * Copyright (C) 2005-2009 Johan Dahlin <johan gnome org>
+ * Copyright (C) 2011 John (J5) Palimier <johnp redhat com>
  *
  *   pygi-invoke.c: main invocation function
  *
@@ -70,13 +71,44 @@ _invoke_function (PyGIInvokeState *state,
 }
 
 static inline gboolean
-_invoke_state_init_from_function_cache(PyGIInvokeState *state,
-                                       PyGIFunctionCache *cache,
-                                       PyObject *py_args)
+_invoke_state_init_from_function_cache (PyGIInvokeState *state,
+                                                                    PyGIFunctionCache *cache,
+                                                                    PyObject *py_args)
 {
     state->py_in_args = py_args;
-    state->n_py_in_args = PySequence_Length(py_args);
-    state->args = g_slice_alloc0(cache->n_args * sizeof(GIArgument *));
+    state->n_py_in_args = PySequence_Length (py_args);
+
+    /* We don't use the class parameter sent in by  the structure
+     * so we remove it from the py_args tuple but we keep it 
+     * around just in case we want to call actual gobject constructors
+     * in the future instead of calling g_object_new
+     */
+    if  (cache->is_constructor) {
+        state->constructor_class = PyTuple_GetItem (py_args, 0);
+
+        if (state->constructor_class == NULL) {
+            PyErr_Clear ();
+            PyErr_Format(PyExc_TypeError,
+                     "Constructors require the class to be passed in as an argument, "
+                     "No arguments passed to the %s constructor.",
+                     cache->name);
+            return FALSE;
+        }
+
+        Py_INCREF(state->constructor_class);
+
+        state->n_py_in_args--;
+
+        /* we could optimize this by using offsets instead of modifying the tuple but it makes the
+         * code more error prone and confusing so don't do that unless profiling shows
+         * significant gain
+         */
+        state->py_in_args = PyTuple_GetSlice (py_args, 1, state->py_in_args);
+
+        Py_DECREF(py_args);
+    }
+
+    state->args = g_slice_alloc0 (cache->n_args * sizeof (GIArgument *));
     if (state->args == NULL && cache->n_args != 0) {
         PyErr_NoMemory();
         return FALSE;
@@ -309,7 +341,9 @@ _invoke_marshal_out_args(PyGIInvokeState *state, PyGIFunctionCache *cache)
 }
 
 PyObject *
-_wrap_g_function_info_invoke (PyGIBaseInfo *self, PyObject *py_args)
+_wrap_g_callable_info_invoke (PyGIBaseInfo *self,
+                              PyObject *py_args,
+                              PyObject *kwargs)
 {
     PyGIInvokeState state = { 0, };
     PyObject *ret;
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index 068fb66..fb3bfea 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -10,6 +10,7 @@ G_BEGIN_DECLS
 typedef struct _PyGIInvokeState
 {
     PyObject *py_in_args;
+    PyObject *constructor_class;
     gssize n_py_in_args;
 
     GIArgument **args;



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