summaryrefslogtreecommitdiff
path: root/gi/pygi-invoke.c
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2013-07-27 15:25:20 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2013-07-27 15:25:20 -0700
commitf5e3876dee512ca82af6ea798b10d5ecad785dd1 (patch)
tree94e38f2d48b82d9a6a85f9096079ba39bf0595cf /gi/pygi-invoke.c
parent91c49822363d8a1efc82163b46daa667d6cfc1b7 (diff)
downloadpygobject-f5e3876dee512ca82af6ea798b10d5ecad785dd1.tar.gz
Cleanup invoke args and kwargs combiner code
Change _py_args_combine_and_check_length use cleaner reference counting. It no longer DECREFs input arguments and always returns a new value reference. Use PyGICallableCache directly as an argument instead of passing various members.
Diffstat (limited to 'gi/pygi-invoke.c')
-rw-r--r--gi/pygi-invoke.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index ec5da91d..17cd278e 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -136,22 +136,14 @@ _check_for_unexpected_kwargs (const gchar *function_name,
/**
* _py_args_combine_and_check_length:
- * @function_name: the name of the function being called. Used for error messages.
- * @arg_name_list: a list of the string names for each argument. The length
- * of this list is the number of required arguments for the
- * function. If an argument has no name, NULL is put in its
- * position in the list.
- * @py_args: the tuple of positional arguments. A referece is stolen, and this
- tuple will be either decreffed or returned as is.
+ * @cache: PyGICallableCache
+ * @py_args: the tuple of positional arguments.
* @py_kwargs: the dict of keyword arguments to be merged with py_args.
- * A reference is borrowed.
*
- * Returns: The py_args and py_kwargs combined into one tuple.
+ * Returns: New value reference to the combined py_args and py_kwargs.
*/
static PyObject *
-_py_args_combine_and_check_length (const gchar *function_name,
- GSList *arg_name_list,
- GHashTable *arg_name_hash,
+_py_args_combine_and_check_length (PyGICallableCache *cache,
PyObject *py_args,
PyObject *py_kwargs)
{
@@ -159,6 +151,7 @@ _py_args_combine_and_check_length (const gchar *function_name,
Py_ssize_t n_py_args, n_py_kwargs, i;
guint n_expected_args;
GSList *l;
+ const gchar *function_name = cache->name;
n_py_args = PyTuple_GET_SIZE (py_args);
if (py_kwargs == NULL)
@@ -166,8 +159,10 @@ _py_args_combine_and_check_length (const gchar *function_name,
else
n_py_kwargs = PyDict_Size (py_kwargs);
- n_expected_args = g_slist_length (arg_name_list);
+ /* Fast path, we already have the exact number of args and not kwargs. */
+ n_expected_args = g_slist_length (cache->arg_name_list);
if (n_py_kwargs == 0 && n_py_args == n_expected_args) {
+ Py_INCREF (py_args);
return py_args;
}
@@ -179,15 +174,12 @@ _py_args_combine_and_check_length (const gchar *function_name,
n_py_kwargs > 0 ? "non-keyword " : "",
n_expected_args == 1 ? "" : "s",
n_py_args);
-
- Py_DECREF (py_args);
return NULL;
}
if (n_py_kwargs > 0 && !_check_for_unexpected_kwargs (function_name,
- arg_name_hash,
+ cache->arg_name_hash,
py_kwargs)) {
- Py_DECREF (py_args);
return NULL;
}
@@ -201,9 +193,7 @@ _py_args_combine_and_check_length (const gchar *function_name,
PyTuple_SET_ITEM (combined_py_args, i, item);
}
- Py_CLEAR(py_args);
-
- for (i = 0, l = arg_name_list; i < n_expected_args && l; i++, l = l->next) {
+ for (i = 0, l = cache->arg_name_list; i < n_expected_args && l; i++, l = l->next) {
PyObject *py_arg_item, *kw_arg_item = NULL;
const gchar *arg_name = l->data;
@@ -250,6 +240,7 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
PyObject *py_args,
PyObject *kwargs)
{
+ PyObject *combined_args = NULL;
state->implementor_gtype = 0;
/* TODO: We don't use the class parameter sent in by the structure
@@ -292,17 +283,16 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
* 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, PyTuple_Size (py_args));
+ combined_args = PyTuple_GetSlice (py_args, 1, PyTuple_Size (py_args));
} else {
- state->py_in_args = py_args;
- Py_INCREF (state->py_in_args);
+ combined_args = py_args;
+ Py_INCREF (combined_args);
}
- state->py_in_args = _py_args_combine_and_check_length (cache->name,
- cache->arg_name_list,
- cache->arg_name_hash,
- state->py_in_args,
+ state->py_in_args = _py_args_combine_and_check_length (cache,
+ combined_args,
kwargs);
+ Py_DECREF (combined_args);
if (state->py_in_args == NULL) {
return FALSE;