Example #1
0
static int
pygtk_tree_model_row_setitem(PyGtkTreeModelRow *self, Py_ssize_t column,
			     PyObject *pyvalue)
{
    gint n_columns;
    GValue value = { 0, };

    if (!GTK_IS_LIST_STORE(self->model) && !GTK_IS_TREE_STORE(self->model)) {
	PyErr_SetString(PyExc_TypeError,
			"can not set cells in this tree model");
	return -1;
    }

    n_columns = gtk_tree_model_get_n_columns(self->model);
    if (column < 0 || column >= n_columns) {
	PyErr_SetString(PyExc_IndexError, "column index out of range");
        return -1;
    }
    g_value_init(&value, gtk_tree_model_get_column_type(self->model, column));
    if (pyg_value_from_pyobject(&value, pyvalue)) {
	PyErr_SetString(PyExc_TypeError,
			"value is of wrong type for this column");
	return -1;
    }
    if (GTK_IS_LIST_STORE(self->model))
	gtk_list_store_set_value(GTK_LIST_STORE(self->model), &self->iter,
				 column, &value);
    else if (GTK_IS_TREE_STORE(self->model))
	gtk_tree_store_set_value(GTK_TREE_STORE(self->model), &self->iter,
				 column, &value);
    g_value_unset(&value);
    return 0;
}
Example #2
0
void
_moo_pyobject_to_gvalue (PyObject *object,
                         GValue   *value)
{
    GType type;

    g_return_if_fail (value != NULL && !G_IS_VALUE (value));
    g_return_if_fail (object != NULL);

    type = pyg_type_from_object (object);

    if (type != 0 && type != G_TYPE_NONE)
    {
        g_value_init (value, type);

        if (pyg_value_from_pyobject (value, object) == 0)
            return;

        g_critical ("oops");
        g_value_unset (value);
    }

    PyErr_Clear ();
    g_value_init (value, MOO_TYPE_PY_OBJECT);

    if (object != Py_None)
        g_value_set_boxed (value, object);
    else
        g_value_set_boxed (value, NULL);
}
Example #3
0
static PyObject *
_wrap_test_value(PyObject *self, PyObject *args)
{
  GValue tvalue = {0,}, *value = &tvalue;
  PyObject *obj;

  if (!PyArg_ParseTuple(args, "O", &obj))
    return NULL;

  g_value_init(value, G_TYPE_VALUE);
  if (pyg_value_from_pyobject(value, obj)) {
    PyErr_SetString(PyExc_TypeError, "Could not convert to GValue");
    return NULL;
  }
  
  return pyg_value_as_pyobject(value, FALSE);
}
Example #4
0
static int
gi_gst_list_to_value (GValue * value, PyObject * object)
{
  gint len, i;

  len = PySequence_Length (object);

  for (i = 0; i < len; i++) {
    GValue v = G_VALUE_INIT;
    GType type;
    PyObject *item;

    item = PySequence_GetItem (object, i);

    if (item == Py_None)
      type = G_TYPE_POINTER;
    else
      type = pyg_type_from_object ((PyObject *) Py_TYPE (item));

    if (type == G_TYPE_NONE) {
      Py_DECREF (item);
      goto fail;
    }

    g_value_init (&v, type);

    if (pyg_value_from_pyobject (&v, item) < 0) {
      Py_DECREF (item);
      goto fail;
    }

    gst_value_list_append_and_take_value (value, &v);
    Py_DECREF (item);
  }

  return 0;

fail:
  PyErr_SetString (PyExc_KeyError,
      "Object is not compatible with Gst.ValueList");
  return -1;
}
Example #5
0
static PyObject *
_wrap_test_value_array(PyObject *self, PyObject *args)
{
  GValue tvalue = {0,}, *value = &tvalue;
  PyObject *obj;

  if (!PyArg_ParseTuple(args, "O", &obj))
    return NULL;

  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
  g_value_init(value, G_TYPE_VALUE_ARRAY);
  G_GNUC_END_IGNORE_DEPRECATIONS

  if (pyg_value_from_pyobject(value, obj)) {
    PyErr_SetString(PyExc_TypeError, "Could not convert to GValueArray");
    return NULL;
  }
  
  return pyg_value_as_pyobject(value, FALSE);
}
Example #6
0
static void
pyg_signal_class_closure_marshal(GClosure *closure,
				 GValue *return_value,
				 guint n_param_values,
				 const GValue *param_values,
				 gpointer invocation_hint,
				 gpointer marshal_data)
{
    PyGILState_STATE state;
    GObject *object;
    PyObject *object_wrapper;
    GSignalInvocationHint *hint = (GSignalInvocationHint *)invocation_hint;
    gchar *method_name, *tmp;
    PyObject *method;
    PyObject *params, *ret;
    guint i, len;

    state = pyglib_gil_state_ensure();

    g_return_if_fail(invocation_hint != NULL);
    /* get the object passed as the first argument to the closure */
    object = g_value_get_object(&param_values[0]);
    g_return_if_fail(object != NULL && G_IS_OBJECT(object));

    /* get the wrapper for this object */
    object_wrapper = pygobject_new(object);
    g_return_if_fail(object_wrapper != NULL);

    /* construct method name for this class closure */
    method_name = g_strconcat("do_", g_signal_name(hint->signal_id), NULL);

    /* convert dashes to underscores.  For some reason, g_signal_name
     * seems to convert all the underscores in the signal name to
       dashes??? */
    for (tmp = method_name; *tmp != '\0'; tmp++)
	if (*tmp == '-') *tmp = '_';

    method = PyObject_GetAttrString(object_wrapper, method_name);
    g_free(method_name);

    if (!method) {
	PyErr_Clear();
	Py_DECREF(object_wrapper);
	pyglib_gil_state_release(state);
	return;
    }
    Py_DECREF(object_wrapper);

    /* construct Python tuple for the parameter values; don't copy boxed values
       initially because we'll check after the call to see if a copy is needed. */
    params = PyTuple_New(n_param_values - 1);
    for (i = 1; i < n_param_values; i++) {
	PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);

	/* error condition */
	if (!item) {
	    Py_DECREF(params);
	    pyglib_gil_state_release(state);
	    return;
	}
	PyTuple_SetItem(params, i - 1, item);
    }

    ret = PyObject_CallObject(method, params);

    /* Copy boxed values if others ref them, this needs to be done regardless of
       exception status. */
    len = PyTuple_Size(params);
    for (i = 0; i < len; i++) {
	PyObject *item = PyTuple_GetItem(params, i);
	if (item != NULL && PyObject_TypeCheck(item, &PyGBoxed_Type)
	    && item->ob_refcnt != 1) {
	    PyGBoxed* boxed_item = (PyGBoxed*)item;
	    if (!boxed_item->free_on_dealloc) {
		gpointer boxed_ptr = pyg_boxed_get_ptr (boxed_item);
		pyg_boxed_set_ptr (boxed_item, g_boxed_copy (boxed_item->gtype, boxed_ptr));
		boxed_item->free_on_dealloc = TRUE;
	    }
	}
    }

    if (ret == NULL) {
	PyErr_Print();
	Py_DECREF(method);
	Py_DECREF(params);
	pyglib_gil_state_release(state);
	return;
    }
    Py_DECREF(method);
    Py_DECREF(params);
    if (G_IS_VALUE(return_value))
	pyg_value_from_pyobject(return_value, ret);
    Py_DECREF(ret);
    pyglib_gil_state_release(state);
}
Example #7
0
static void
pyg_closure_marshal(GClosure *closure,
		    GValue *return_value,
		    guint n_param_values,
		    const GValue *param_values,
		    gpointer invocation_hint,
		    gpointer marshal_data)
{
    PyGILState_STATE state;
    PyGClosure *pc = (PyGClosure *)closure;
    PyObject *params, *ret;
    guint i;

    state = pyglib_gil_state_ensure();

    /* construct Python tuple for the parameter values */
    params = PyTuple_New(n_param_values);
    for (i = 0; i < n_param_values; i++) {
	/* swap in a different initial data for connect_object() */
	if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
	    g_return_if_fail(pc->swap_data != NULL);
	    Py_INCREF(pc->swap_data);
	    PyTuple_SetItem(params, 0, pc->swap_data);
	} else {
	    PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);

	    /* error condition */
	    if (!item) {
            if (!PyErr_Occurred ())
                PyErr_SetString (PyExc_TypeError,
                                 "can't convert parameter to desired type");

            if (pc->exception_handler)
                pc->exception_handler (return_value, n_param_values, param_values);
            else
                PyErr_Print();

            goto out;
	    }
	    PyTuple_SetItem(params, i, item);
	}
    }
    /* params passed to function may have extra arguments */
    if (pc->extra_args) {
	PyObject *tuple = params;
	params = PySequence_Concat(tuple, pc->extra_args);
	Py_DECREF(tuple);
    }
    ret = PyObject_CallObject(pc->callback, params);
    if (ret == NULL) {
	if (pc->exception_handler)
	    pc->exception_handler(return_value, n_param_values, param_values);
	else
	    PyErr_Print();
	goto out;
    }

    if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) {
	/* If we already have an exception set, use that, otherwise set a
	 * generic one */
	if (!PyErr_Occurred())
	    PyErr_SetString(PyExc_TypeError,
                            "can't convert return value to desired type");

	if (pc->exception_handler)
	    pc->exception_handler(return_value, n_param_values, param_values);
	else
	    PyErr_Print();
    }
    Py_DECREF(ret);

 out:
    Py_DECREF(params);
    pyglib_gil_state_release(state);
}
Example #8
0
int
_pygtk_tree_model_set_row(GtkTreeModel *model, GtkTreeIter *iter,
			  PyObject *items)
{
    gint n_columns, i;
    GtkTreeModel *child;
    GtkTreeIter citer;

    if (!GTK_IS_LIST_STORE(model) && !GTK_IS_TREE_STORE(model) &&
        !GTK_IS_TREE_MODEL_SORT(model) && !GTK_IS_TREE_MODEL_FILTER(model)) {
	PyErr_SetString(PyExc_TypeError,
			"cannot set cells in this tree model");
	return -1;
    }

    if (GTK_IS_TREE_MODEL_SORT(model)) {
        child = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model));
        gtk_tree_model_sort_convert_iter_to_child_iter(
            GTK_TREE_MODEL_SORT(model), &citer, iter);
        return _pygtk_tree_model_set_row(child, &citer, items);
    }

    if (GTK_IS_TREE_MODEL_FILTER(model)) {
        child = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
        gtk_tree_model_filter_convert_iter_to_child_iter(
            GTK_TREE_MODEL_FILTER(model), &citer, iter);
        return _pygtk_tree_model_set_row(child, &citer, items);
    }

    if (!PySequence_Check(items)) {
	PyErr_SetString(PyExc_TypeError, "expecting a sequence");
	return -1;
    }
    n_columns = gtk_tree_model_get_n_columns(model);
    if (PySequence_Length(items) != n_columns) {
	PyErr_SetString(PyExc_ValueError, "row sequence has wrong length");
	return -1;
    }
    for (i = 0; i < n_columns; i++) {
	GValue value = { 0, };
	PyObject *item;

	item = PySequence_GetItem(items, i);
	if (!item)
	    return -1;
	g_value_init(&value, gtk_tree_model_get_column_type(model, i));
	if (pyg_value_from_pyobject(&value, item)) {
	    Py_DECREF(item);
	    PyErr_SetString(PyExc_TypeError,
			    "value is of wrong type for this column");
	    return -1;
	}

	if (GTK_IS_LIST_STORE(model))
	    gtk_list_store_set_value(GTK_LIST_STORE(model), iter, i, &value);
	else if (GTK_IS_TREE_STORE(model))
	    gtk_tree_store_set_value(GTK_TREE_STORE(model), iter, i, &value);

	g_value_unset(&value);
	Py_DECREF(item);
    }
    return 0;
}
Example #9
0
static void
pygi_signal_closure_marshal(GClosure *closure,
                            GValue *return_value,
                            guint n_param_values,
                            const GValue *param_values,
                            gpointer invocation_hint,
                            gpointer marshal_data)
{
    PyGILState_STATE state;
    PyGClosure *pc = (PyGClosure *)closure;
    PyObject *params, *ret = NULL;
    guint i;
    GISignalInfo *signal_info;
    gint n_sig_info_args;
    gint sig_info_highest_arg;
    GSList *list_item = NULL;
    GSList *pass_by_ref_structs = NULL;

    state = PyGILState_Ensure();

    signal_info = ((PyGISignalClosure *)closure)->signal_info;
    n_sig_info_args = g_callable_info_get_n_args(signal_info);
    /* the first argument to a signal callback is instance,
       but instance is not counted in the introspection data */
    sig_info_highest_arg = n_sig_info_args + 1;
    g_assert_cmpint(sig_info_highest_arg, ==, n_param_values);

    /* construct Python tuple for the parameter values */
    params = PyTuple_New(n_param_values);
    for (i = 0; i < n_param_values; i++) {
        /* swap in a different initial data for connect_object() */
        if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) {
            g_return_if_fail(pc->swap_data != NULL);
            Py_INCREF(pc->swap_data);
            PyTuple_SetItem(params, 0, pc->swap_data);

        } else if (i == 0) {
            PyObject *item = pyg_value_as_pyobject(&param_values[i], FALSE);

            if (!item) {
                goto out;
            }
            PyTuple_SetItem(params, i, item);

        } else if (i < sig_info_highest_arg) {
            GIArgInfo arg_info;
            GITypeInfo type_info;
            GITypeTag type_tag;
            GIArgument arg = { 0, };
            PyObject *item = NULL;
            gboolean free_array = FALSE;
            gboolean pass_struct_by_ref = FALSE;

            g_callable_info_load_arg(signal_info, i - 1, &arg_info);
            g_arg_info_load_type(&arg_info, &type_info);

            arg = _pygi_argument_from_g_value(&param_values[i], &type_info);

            type_tag = g_type_info_get_tag (&type_info);
            if (type_tag == GI_TYPE_TAG_ARRAY) {
                /* Skip the self argument of param_values */
                arg.v_pointer = _pygi_argument_to_array (&arg,
                                                         _pygi_argument_array_length_marshal,
                                                         (void *)(param_values + 1),
                                                         signal_info,
                                                         &type_info,
                                                         &free_array);
            }

            /* Hack to ensure struct arguments are passed-by-reference allowing
             * callback implementors to modify the struct values. This is needed
             * for keeping backwards compatibility and should be removed in future
             * versions which support signal output arguments as return values.
             * See: https://bugzilla.gnome.org/show_bug.cgi?id=735486
             *
             * Note the logic here must match the logic path taken in _pygi_argument_to_object.
             */
            if (type_tag == GI_TYPE_TAG_INTERFACE) {
                GIBaseInfo *info = g_type_info_get_interface (&type_info);
                GIInfoType info_type = g_base_info_get_type (info);

                if (info_type == GI_INFO_TYPE_STRUCT ||
                        info_type == GI_INFO_TYPE_BOXED ||
                        info_type == GI_INFO_TYPE_UNION) {

                    GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
                    gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) &&
                                          (g_struct_info_is_foreign ((GIStructInfo *) info));

                    if (!is_foreign && !g_type_is_a (gtype, G_TYPE_VALUE) &&
                            g_type_is_a (gtype, G_TYPE_BOXED)) {
                        pass_struct_by_ref = TRUE;
                    }
                }

                g_base_info_unref (info);
            }

            if (pass_struct_by_ref) {
                /* transfer everything will ensure the struct is not copied when wrapped. */
                item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_EVERYTHING);
                if (item && PyObject_IsInstance (item, (PyObject *) &PyGIBoxed_Type)) {
                    ((PyGBoxed *)item)->free_on_dealloc = FALSE;
                    pass_by_ref_structs = g_slist_prepend (pass_by_ref_structs, item);
                }

            } else {
                item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_NOTHING);
            }

            if (free_array) {
                g_array_free (arg.v_pointer, FALSE);
            }

            if (item == NULL) {
                PyErr_Print ();
                goto out;
            }
            PyTuple_SetItem(params, i, item);
        }
    }
    /* params passed to function may have extra arguments */
    if (pc->extra_args) {
        PyObject *tuple = params;
        params = PySequence_Concat(tuple, pc->extra_args);
        Py_DECREF(tuple);
    }
    ret = PyObject_CallObject(pc->callback, params);
    if (ret == NULL) {
        if (pc->exception_handler)
            pc->exception_handler(return_value, n_param_values, param_values);
        else
            PyErr_Print();
        goto out;
    }

    if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) {
        PyErr_SetString(PyExc_TypeError,
                        "can't convert return value to desired type");

        if (pc->exception_handler)
            pc->exception_handler(return_value, n_param_values, param_values);
        else
            PyErr_Print();
    }
    Py_DECREF(ret);

    /* Run through the list of structs which have been passed by reference and
     * check if they are being held longer than the duration of the callback
     * execution. This is determined if the ref count is greater than 1.
     * A single ref is held by the argument list and any more would mean the callback
     * stored a ref somewhere else. In this case we make an internal copy of
     * the boxed struct so Python can own the memory to it.
     */
    list_item = pass_by_ref_structs;
    while (list_item) {
        PyObject *item = list_item->data;
        if (item->ob_refcnt > 1) {
            _pygi_boxed_copy_in_place ((PyGIBoxed *)item);
        }
        list_item = g_slist_next (list_item);
    }

 out:
    g_slist_free (pass_by_ref_structs);
    Py_DECREF(params);
    PyGILState_Release(state);
}
Example #10
0
/**
 * pyg_value_from_pyobject:
 * @value: the GValue object to store the converted value in.
 * @obj: the Python object to convert.
 *
 * This function converts a Python object and stores the result in a
 * GValue.  The GValue must be initialised in advance with
 * g_value_init().  If the Python object can't be converted to the
 * type of the GValue, then an error is returned.
 *
 * Returns: 0 on success, -1 on error.
 */
int
pyg_value_from_pyobject(GValue *value, PyObject *obj)
{
    PyObject *tmp;

    switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value))) {
    case G_TYPE_INTERFACE:
	/* we only handle interface types that have a GObject prereq */
	if (g_type_is_a(G_VALUE_TYPE(value), G_TYPE_OBJECT)) {
	    if (obj == Py_None)
		g_value_set_object(value, NULL);
	    else {
		if (!PyObject_TypeCheck(obj, &PyGObject_Type)) {
		    return -1;
		}
		if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
						G_VALUE_TYPE(value))) {
		    return -1;
		}
		g_value_set_object(value, pygobject_get(obj));
	    }
	} else {
	    return -1;
	}
	break;
    case G_TYPE_CHAR:
#if PY_VERSION_HEX < 0x03000000
	if (PyString_Check(obj)) {
	    g_value_set_char(value, PyString_AsString(obj)[0]);
	} else
#endif
	if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_char(value, PYGLIB_PyBytes_AsString(tmp)[0]);
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}

	break;
    case G_TYPE_UCHAR:
	if (PYGLIB_PyLong_Check(obj)) {
	    glong val;
	    val = PYGLIB_PyLong_AsLong(obj);
	    if (val >= 0 && val <= 255)
	      g_value_set_uchar(value, (guchar)PYGLIB_PyLong_AsLong (obj));
	    else
	      return -1;
#if PY_VERSION_HEX < 0x03000000
	} else if (PyString_Check(obj)) {
	    g_value_set_uchar(value, PyString_AsString(obj)[0]);
#endif
	} else if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_uchar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}
	break;
    case G_TYPE_BOOLEAN:
	g_value_set_boolean(value, PyObject_IsTrue(obj));
	break;
    case G_TYPE_INT:
	g_value_set_int(value, PYGLIB_PyLong_AsLong(obj));
	break;
    case G_TYPE_UINT:
	{
	    if (PYGLIB_PyLong_Check(obj)) {
		glong val;

		val = PYGLIB_PyLong_AsLong(obj);
		if (val >= 0 && val <= G_MAXUINT)
		    g_value_set_uint(value, (guint)val);
		else
		    return -1;
	    } else {
		g_value_set_uint(value, PyLong_AsUnsignedLong(obj));
	    }
	}
	break;
    case G_TYPE_LONG:
	g_value_set_long(value, PYGLIB_PyLong_AsLong(obj));
	break;
    case G_TYPE_ULONG:
#if PY_VERSION_HEX < 0x03000000
	if (PyInt_Check(obj)) {
            long val;

            val = PYGLIB_PyLong_AsLong(obj);
            if (val < 0) {
                PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
                return -1;
            }
            g_value_set_ulong(value, (gulong)val);
        } else
#endif
        if (PyLong_Check(obj))
	    g_value_set_ulong(value, PyLong_AsUnsignedLong(obj));
        else
            return -1;
        break;
    case G_TYPE_INT64:
	g_value_set_int64(value, PyLong_AsLongLong(obj));
	break;
    case G_TYPE_UINT64:
#if PY_VERSION_HEX < 0x03000000
        if (PyInt_Check(obj)) {
            long v = PyInt_AsLong(obj);
            if (v < 0) {
                PyErr_SetString(PyExc_OverflowError, "negative value not allowed for uint64 property");
                return -1;
            }
            g_value_set_uint64(value, v);
        } else
#endif
        if (PyLong_Check(obj))
            g_value_set_uint64(value, PyLong_AsUnsignedLongLong(obj));
        else
            return -1;
	break;
    case G_TYPE_ENUM:
	{
	    gint val = 0;
	    if (pyg_enum_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
		PyErr_Clear();
		return -1;
	    }
	    g_value_set_enum(value, val);
	}
	break;
    case G_TYPE_FLAGS:
	{
	    gint val = 0;
	    if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
		PyErr_Clear();
		return -1;
	    }
	    g_value_set_flags(value, val);
	}
	break;
    case G_TYPE_FLOAT:
	g_value_set_float(value, PyFloat_AsDouble(obj));
	break;
    case G_TYPE_DOUBLE:
	g_value_set_double(value, PyFloat_AsDouble(obj));
	break;
    case G_TYPE_STRING:
	if (obj == Py_None) {
	    g_value_set_string(value, NULL);
#if PY_VERSION_HEX < 0x03000000
	} else if (PyString_Check(obj)) {
	    g_value_set_string(value, PyString_AsString(obj));
#endif
	} else if (PyUnicode_Check(obj)) {
	    tmp = PyUnicode_AsUTF8String(obj);
	    g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp));
	    Py_DECREF(tmp);
	} else {
	    PyErr_Clear();
	    return -1;
	}
	break;
    case G_TYPE_POINTER:
	if (obj == Py_None)
	    g_value_set_pointer(value, NULL);
	else if (PyObject_TypeCheck(obj, &PyGPointer_Type) &&
		   G_VALUE_HOLDS(value, ((PyGPointer *)obj)->gtype))
	    g_value_set_pointer(value, pyg_pointer_get(obj, gpointer));
	else if (PYGLIB_CPointer_Check(obj))
	    g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    case G_TYPE_BOXED: {
	PyGTypeMarshal *bm;

	if (obj == Py_None)
	    g_value_set_boxed(value, NULL);
	else if (G_VALUE_HOLDS(value, PY_TYPE_OBJECT))
	    g_value_set_boxed(value, obj);
	else if (PyObject_TypeCheck(obj, &PyGBoxed_Type) &&
		   G_VALUE_HOLDS(value, ((PyGBoxed *)obj)->gtype))
	    g_value_set_boxed(value, pyg_boxed_get(obj, gpointer));
        else if (G_VALUE_HOLDS(value, G_TYPE_VALUE)) {
            GType type;
            GValue *n_value;

            type = pyg_type_from_object((PyObject*)Py_TYPE(obj));
            if (G_UNLIKELY (! type)) {
                PyErr_Clear();
                return -1;
            }
            n_value = g_new0 (GValue, 1);
            g_value_init (n_value, type);
            g_value_take_boxed (value, n_value);
            return pyg_value_from_pyobject (n_value, obj);
        }
        else if (PySequence_Check(obj) &&
		   G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
	    return pyg_value_array_from_pyobject(value, obj, NULL);
	else if (PYGLIB_PyUnicode_Check(obj) &&
                 G_VALUE_HOLDS(value, G_TYPE_GSTRING)) {
            GString *string;
            char *buffer;
            Py_ssize_t len;
            if (PYGLIB_PyUnicode_AsStringAndSize(obj, &buffer, &len))
                return -1;
            string = g_string_new_len(buffer, len);
	    g_value_set_boxed(value, string);
	    g_string_free (string, TRUE);
            break;
        }
	else if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
	    return bm->tovalue(value, obj);
	else if (PYGLIB_CPointer_Check(obj))
	    g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    }
    case G_TYPE_PARAM:
	if (PyGParamSpec_Check(obj))
	    g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
	else
	    return -1;
	break;
    case G_TYPE_OBJECT:
	if (obj == Py_None) {
	    g_value_set_object(value, NULL);
	} else if (PyObject_TypeCheck(obj, &PyGObject_Type) &&
		   G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
					      G_VALUE_TYPE(value))) {
	    g_value_set_object(value, pygobject_get(obj));
	} else
	    return -1;
	break;
    default:
	{
	    PyGTypeMarshal *bm;
	    if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
		return bm->tovalue(value, obj);
	    break;
	}
    }
    if (PyErr_Occurred()) {
        g_value_unset(value);
        PyErr_Clear();
        return -1;
    }
    return 0;
}
Example #11
0
static int
pyg_value_array_from_pyobject(GValue *value,
			      PyObject *obj,
			      const GParamSpecValueArray *pspec)
{
    int len;
    GValueArray *value_array;
    int i;

    len = PySequence_Length(obj);
    if (len == -1) {
	PyErr_Clear();
	return -1;
    }

    if (pspec && pspec->fixed_n_elements > 0 && len != pspec->fixed_n_elements)
	return -1;

    value_array = g_value_array_new(len);

    for (i = 0; i < len; ++i) {
	PyObject *item = PySequence_GetItem(obj, i);
	GType type;
	GValue item_value = { 0, };
	int status;

	if (! item) {
	    PyErr_Clear();
	    g_value_array_free(value_array);
	    return -1;
	}

	if (pspec && pspec->element_spec)
	    type = G_PARAM_SPEC_VALUE_TYPE(pspec->element_spec);
	else if (item == Py_None)
	    type = G_TYPE_POINTER; /* store None as NULL */
	else {
	    type = pyg_type_from_object((PyObject*)Py_TYPE(item));
	    if (! type) {
		PyErr_Clear();
		g_value_array_free(value_array);
		Py_DECREF(item);
		return -1;
	    }
	}

	g_value_init(&item_value, type);
	status = (pspec && pspec->element_spec)
	    ? pyg_param_gvalue_from_pyobject(&item_value, item, pspec->element_spec)
	    : pyg_value_from_pyobject(&item_value, item);
	Py_DECREF(item);

	if (status == -1) {
	    g_value_array_free(value_array);
	    g_value_unset(&item_value);
	    return -1;
	}

	g_value_array_append(value_array, &item_value);
	g_value_unset(&item_value);
    }

    g_value_take_boxed(value, value_array);
    return 0;
}