static gboolean _pygi_marshal_from_py_void (PyGIInvokeState *state, PyGICallableCache *callable_cache, PyGIArgCache *arg_cache, PyObject *py_arg, GIArgument *arg, gpointer *cleanup_data) { g_warn_if_fail (arg_cache->transfer == GI_TRANSFER_NOTHING); if (py_arg == Py_None) { arg->v_pointer = NULL; } else if (PYGLIB_CPointer_Check(py_arg)) { arg->v_pointer = PYGLIB_CPointer_GetPointer (py_arg, NULL); } else if (PYGLIB_PyLong_Check(py_arg) || PyLong_Check(py_arg)) { arg->v_pointer = PyLong_AsVoidPtr (py_arg); } else { PyErr_SetString(PyExc_ValueError, "Pointer arguments are restricted to integers, capsules, and None. " "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); return FALSE; } *cleanup_data = arg->v_pointer; return TRUE; }
/** * pyg_enum_get_value: * @enum_type: the GType of the flag. * @obj: a Python object representing the flag value * @val: a pointer to the location to store the integer representation of the flag. * * Converts a Python object to the integer equivalent. The conversion * will depend on the type of the Python object. If the object is an * integer, it is passed through directly. If it is a string, it will * be treated as a full or short enum name as defined in the GType. * * Returns: 0 on success or -1 on failure */ gint pyg_enum_get_value(GType enum_type, PyObject *obj, gint *val) { GEnumClass *eclass = NULL; gint res = -1; g_return_val_if_fail(val != NULL, -1); if (!obj) { *val = 0; res = 0; } else if (PYGLIB_PyLong_Check(obj)) { *val = PYGLIB_PyLong_AsLong(obj); res = 0; if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { g_warning("expected enumeration type %s, but got %s instead", g_type_name(enum_type), g_type_name(((PyGEnum *) obj)->gtype)); } /* Dumb code duplication, but probably not worth it to have yet another macro. */ } else if (PyLong_Check(obj)) { *val = PyLong_AsLong(obj); res = 0; if (PyObject_TypeCheck(obj, &PyGEnum_Type) && ((PyGEnum *) obj)->gtype != enum_type) { g_warning("expected enumeration type %s, but got %s instead", g_type_name(enum_type), g_type_name(((PyGEnum *) obj)->gtype)); } } else if (PYGLIB_PyUnicode_Check(obj)) { GEnumValue *info; char *str = PYGLIB_PyUnicode_AsString(obj); if (enum_type != G_TYPE_NONE) eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); else { PyErr_SetString(PyExc_TypeError, "could not convert string to enum because there is no GType associated to look up the value"); res = -1; } info = g_enum_get_value_by_name(eclass, str); g_type_class_unref(eclass); if (!info) info = g_enum_get_value_by_nick(eclass, str); if (info) { *val = info->value; res = 0; } else { PyErr_SetString(PyExc_TypeError, "could not convert string"); res = -1; } } else { PyErr_SetString(PyExc_TypeError,"enum values must be strings or ints"); res = -1; } return res; }
/** * pygi_error_marshal_from_py: * @pyerr: A Python exception instance. * @error: a standard GLib GError ** output parameter * * Converts from a Python implemented GError into a GError. * * Returns: TRUE if the conversion was successful, otherwise a Python exception * is set and FALSE is returned. */ gboolean pygi_error_marshal_from_py (PyObject *pyerr, GError **error) { gboolean res = FALSE; PyObject *py_message = NULL, *py_domain = NULL, *py_code = NULL; if (PyObject_IsInstance (pyerr, PyGError) != 1) { PyErr_Format (PyExc_TypeError, "Must be GLib.Error, not %s", pyerr->ob_type->tp_name); return FALSE; } py_message = PyObject_GetAttrString (pyerr, "message"); if (!py_message || !PYGLIB_PyUnicode_Check (py_message)) { PyErr_SetString (PyExc_ValueError, "GLib.Error instances must have a 'message' string attribute"); goto cleanup; } py_domain = PyObject_GetAttrString (pyerr, "domain"); if (!py_domain || !PYGLIB_PyUnicode_Check (py_domain)) { PyErr_SetString (PyExc_ValueError, "GLib.Error instances must have a 'domain' string attribute"); goto cleanup; } py_code = PyObject_GetAttrString (pyerr, "code"); if (!py_code || !PYGLIB_PyLong_Check (py_code)) { PyErr_SetString (PyExc_ValueError, "GLib.Error instances must have a 'code' int attribute"); goto cleanup; } res = TRUE; g_set_error_literal (error, g_quark_from_string (PYGLIB_PyUnicode_AsString (py_domain)), PYGLIB_PyLong_AsLong (py_code), PYGLIB_PyUnicode_AsString (py_message)); cleanup: Py_XDECREF (py_message); Py_XDECREF (py_code); Py_XDECREF (py_domain); return res; }
static PyObject * pyg_enum_richcompare(PyGEnum *self, PyObject *other, int op) { static char warning[256]; if (!PYGLIB_PyLong_Check(other)) { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } if (PyObject_TypeCheck(other, &PyGEnum_Type) && ((PyGEnum*)other)->gtype != self->gtype) { g_snprintf(warning, sizeof(warning), "comparing different enum types: %s and %s", g_type_name(self->gtype), g_type_name(((PyGEnum*)other)->gtype)); if (PyErr_Warn(PyExc_Warning, warning)) return NULL; } return pyg_integer_richcompare((PyObject *)self, other, op); }
/** * pyg_flags_get_value: * @flag_type: the GType of the flag. * @obj: a Python object representing the flag value * @val: a pointer to the location to store the integer representation of the flag. * * Converts a Python object to the integer equivalent. The conversion * will depend on the type of the Python object. If the object is an * integer, it is passed through directly. If it is a string, it will * be treated as a full or short flag name as defined in the GType. * If it is a tuple, then the items are treated as strings and ORed * together. * * Returns: 0 on success or -1 on failure */ gint pyg_flags_get_value(GType flag_type, PyObject *obj, guint *val) { GFlagsClass *fclass = NULL; gint res = -1; g_return_val_if_fail(val != NULL, -1); if (!obj) { *val = 0; res = 0; } else if (PYGLIB_PyLong_Check(obj)) { *val = PYGLIB_PyLong_AsUnsignedLong(obj); res = 0; } else if (PyLong_Check(obj)) { *val = PyLong_AsLongLong(obj); res = 0; } else if (PYGLIB_PyUnicode_Check(obj)) { GFlagsValue *info; char *str = PYGLIB_PyUnicode_AsString(obj); if (flag_type != G_TYPE_NONE) fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); else { PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); res = -1; } info = g_flags_get_value_by_name(fclass, str); g_type_class_unref(fclass); if (!info) info = g_flags_get_value_by_nick(fclass, str); if (info) { *val = info->value; res = 0; } else { PyErr_SetString(PyExc_TypeError, "could not convert string"); res = -1; } } else if (PyTuple_Check(obj)) { int i, len; len = PyTuple_Size(obj); *val = 0; res = 0; if (flag_type != G_TYPE_NONE) fclass = G_FLAGS_CLASS(g_type_class_ref(flag_type)); else { PyErr_SetString(PyExc_TypeError, "could not convert string to flag because there is no GType associated to look up the value"); res = -1; } for (i = 0; i < len; i++) { PyObject *item = PyTuple_GetItem(obj, i); char *str = PYGLIB_PyUnicode_AsString(item); GFlagsValue *info = g_flags_get_value_by_name(fclass, str); if (!info) info = g_flags_get_value_by_nick(fclass, str); if (info) { *val |= info->value; } else { PyErr_SetString(PyExc_TypeError, "could not convert string"); res = -1; break; } } g_type_class_unref(fclass); } else { PyErr_SetString(PyExc_TypeError, "flag values must be strings, ints, longs, or tuples"); res = -1; } return res; }
gboolean _pygi_marshal_from_py_basic_type (PyObject *object, /* in */ GIArgument *arg, /* out */ GITypeTag type_tag, GITransfer transfer, gpointer *cleanup_data /* out */) { switch (type_tag) { case GI_TYPE_TAG_VOID: g_warn_if_fail (transfer == GI_TRANSFER_NOTHING); if (object == Py_None) { arg->v_pointer = NULL; } else if (!PYGLIB_PyLong_Check(object) && !PyLong_Check(object)) { PyErr_SetString(PyExc_TypeError, "Pointer assignment is restricted to integer values. " "See: https://bugzilla.gnome.org/show_bug.cgi?id=683599"); } else { arg->v_pointer = PyLong_AsVoidPtr (object); *cleanup_data = arg->v_pointer; } break; case GI_TYPE_TAG_INT8: case GI_TYPE_TAG_UINT8: if (PYGLIB_PyBytes_Check (object)) { if (PYGLIB_PyBytes_Size (object) != 1) { PyErr_Format (PyExc_TypeError, "Must be a single character"); return FALSE; } if (type_tag == GI_TYPE_TAG_INT8) { arg->v_int8 = (gint8)(PYGLIB_PyBytes_AsString (object)[0]); } else { arg->v_uint8 = (guint8)(PYGLIB_PyBytes_AsString (object)[0]); } } else { return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); } break; case GI_TYPE_TAG_INT16: case GI_TYPE_TAG_UINT16: case GI_TYPE_TAG_INT32: case GI_TYPE_TAG_UINT32: case GI_TYPE_TAG_INT64: case GI_TYPE_TAG_UINT64: return _pygi_marshal_from_py_long (object, arg, type_tag, transfer); case GI_TYPE_TAG_BOOLEAN: arg->v_boolean = PyObject_IsTrue (object); break; case GI_TYPE_TAG_FLOAT: return _pygi_marshal_from_py_float (object, arg); case GI_TYPE_TAG_DOUBLE: return _pygi_marshal_from_py_double (object, arg); case GI_TYPE_TAG_GTYPE: return _pygi_marshal_from_py_gtype (object, arg); case GI_TYPE_TAG_UNICHAR: return _pygi_marshal_from_py_unichar (object, arg); case GI_TYPE_TAG_UTF8: return _pygi_marshal_from_py_utf8 (object, arg, cleanup_data); case GI_TYPE_TAG_FILENAME: return _pygi_marshal_from_py_filename (object, arg, cleanup_data); default: return FALSE; } if (PyErr_Occurred()) return FALSE; return TRUE; }
static PyObject * _wrap_g_field_info_set_value (PyGIBaseInfo *self, PyObject *args) { PyObject *instance; PyObject *py_value; GIBaseInfo *container_info; GIInfoType container_info_type; gpointer pointer; GITypeInfo *field_type_info; GIArgument value; PyObject *retval = NULL; if (!PyArg_ParseTuple (args, "OO:FieldInfo.set_value", &instance, &py_value)) { return NULL; } container_info = g_base_info_get_container (self->info); g_assert (container_info != NULL); /* Check the instance. */ if (!_pygi_g_registered_type_info_check_object ( (GIRegisteredTypeInfo *) container_info, TRUE, instance)) { _PyGI_ERROR_PREFIX ("argument 1: "); return NULL; } /* Get the pointer to the container. */ container_info_type = g_base_info_get_type (container_info); switch (container_info_type) { case GI_INFO_TYPE_UNION: case GI_INFO_TYPE_STRUCT: pointer = pyg_boxed_get (instance, void); break; case GI_INFO_TYPE_OBJECT: pointer = pygobject_get (instance); break; default: /* Other types don't have fields. */ g_assert_not_reached(); } field_type_info = g_field_info_get_type ( (GIFieldInfo *) self->info); /* Check the value. */ { gboolean retval; retval = _pygi_g_type_info_check_object (field_type_info, py_value, TRUE); if (retval < 0) { goto out; } if (!retval) { _PyGI_ERROR_PREFIX ("argument 2: "); goto out; } } /* Set the field's value. */ /* A few types are not handled by g_field_info_set_field, so do it here. */ if (!g_type_info_is_pointer (field_type_info) && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *info; GIInfoType info_type; if (! (g_field_info_get_flags ( (GIFieldInfo *) self->info) & GI_FIELD_IS_WRITABLE)) { PyErr_SetString (PyExc_RuntimeError, "field is not writable"); goto out; } info = g_type_info_get_interface (field_type_info); info_type = g_base_info_get_type (info); switch (info_type) { case GI_INFO_TYPE_UNION: PyErr_SetString (PyExc_NotImplementedError, "setting an union is not supported yet"); goto out; case GI_INFO_TYPE_STRUCT: { gboolean is_simple; gsize offset; gssize size; is_simple = pygi_g_struct_info_is_simple ( (GIStructInfo *) info); if (!is_simple) { PyErr_SetString (PyExc_TypeError, "cannot set a structure which has no well-defined ownership transfer rules"); g_base_info_unref (info); goto out; } value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING); if (PyErr_Occurred()) { g_base_info_unref (info); goto out; } offset = g_field_info_get_offset ( (GIFieldInfo *) self->info); size = g_struct_info_get_size ( (GIStructInfo *) info); g_assert (size > 0); g_memmove ((char*) pointer + offset, value.v_pointer, size); g_base_info_unref (info); retval = Py_None; goto out; } default: /* Fallback. */ break; } g_base_info_unref (info); } else if (g_type_info_is_pointer (field_type_info) && g_type_info_get_tag (field_type_info) == GI_TYPE_TAG_VOID) { int offset; if (py_value != Py_None && !PYGLIB_PyLong_Check(py_value)) { if (PyErr_WarnEx(PyExc_RuntimeWarning, "Usage of gpointers to store objects is being deprecated. " "Please use integer values only, see: https://bugzilla.gnome.org/show_bug.cgi?id=683599", 1)) goto out; } offset = g_field_info_get_offset ((GIFieldInfo *) self->info); value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_NOTHING); /* Decrement the previous python object stashed on the void pointer. * This seems somewhat dangerous as the code is blindly assuming any * void pointer field stores a python object pointer and then decrefs it. * This is essentially the same as something like: * Py_XDECREF(struct->void_ptr); */ Py_XDECREF(G_STRUCT_MEMBER (gpointer, pointer, offset)); /* Assign and increment the newly assigned object. At this point the value * arg will hold a pointer the python object "py_value" or NULL. * This is essentially: * struct->void_ptr = value.v_pointer; * Py_XINCREF(struct->void_ptr); */ G_STRUCT_MEMBER (gpointer, pointer, offset) = (gpointer)value.v_pointer; Py_XINCREF(G_STRUCT_MEMBER (gpointer, pointer, offset)); retval = Py_None; goto out; } value = _pygi_argument_from_object (py_value, field_type_info, GI_TRANSFER_EVERYTHING); if (PyErr_Occurred()) { goto out; } if (!g_field_info_set_field ( (GIFieldInfo *) self->info, pointer, &value)) { _pygi_argument_release (&value, field_type_info, GI_TRANSFER_NOTHING, GI_DIRECTION_IN); PyErr_SetString (PyExc_RuntimeError, "unable to set value for field"); goto out; } retval = Py_None; out: g_base_info_unref ( (GIBaseInfo *) field_type_info); Py_XINCREF (retval); return retval; }
/** * pygi_gerror_exception_check: * @error: a standard GLib GError ** output parameter * * Checks to see if a GError exception has been raised, and if so * translates the python exception to a standard GLib GError. If the * raised exception is not a GError then PyErr_Print() is called. * * Returns: 0 if no exception has been raised, -1 if it is a * valid glib.GError, -2 otherwise. */ gboolean pygi_gerror_exception_check (GError **error) { PyObject *type, *value, *traceback; PyObject *py_message, *py_domain, *py_code; const char *bad_gerror_message; PyErr_Fetch(&type, &value, &traceback); if (type == NULL) return 0; PyErr_NormalizeException(&type, &value, &traceback); if (value == NULL) { PyErr_Restore(type, value, traceback); PyErr_Print(); return -2; } if (!value || !PyErr_GivenExceptionMatches(type, (PyObject *) PyGError)) { PyErr_Restore(type, value, traceback); PyErr_Print(); return -2; } Py_DECREF(type); Py_XDECREF(traceback); py_message = PyObject_GetAttrString(value, "message"); if (!py_message || !PYGLIB_PyUnicode_Check(py_message)) { bad_gerror_message = "GLib.Error instances must have a 'message' string attribute"; Py_XDECREF(py_message); goto bad_gerror; } py_domain = PyObject_GetAttrString(value, "domain"); if (!py_domain || !PYGLIB_PyUnicode_Check(py_domain)) { bad_gerror_message = "GLib.Error instances must have a 'domain' string attribute"; Py_DECREF(py_message); Py_XDECREF(py_domain); goto bad_gerror; } py_code = PyObject_GetAttrString(value, "code"); if (!py_code || !PYGLIB_PyLong_Check(py_code)) { bad_gerror_message = "GLib.Error instances must have a 'code' int attribute"; Py_DECREF(py_message); Py_DECREF(py_domain); Py_XDECREF(py_code); goto bad_gerror; } g_set_error(error, g_quark_from_string(PYGLIB_PyUnicode_AsString(py_domain)), PYGLIB_PyLong_AsLong(py_code), "%s", PYGLIB_PyUnicode_AsString(py_message)); Py_DECREF(py_message); Py_DECREF(py_code); Py_DECREF(py_domain); return -1; bad_gerror: Py_DECREF(value); g_set_error(error, g_quark_from_static_string("pygi"), 0, "%s", bad_gerror_message); PyErr_SetString(PyExc_ValueError, bad_gerror_message); PyErr_Print(); return -2; }
/** * 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; }