コード例 #1
0
ファイル: pygi-error.c プロジェクト: RIFTIO/pygobject
/**
 * 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;
}
コード例 #2
0
ファイル: pygtype.c プロジェクト: RIFTIO/pygobject
/**
 * 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;
}
コード例 #3
0
ファイル: pygtype.c プロジェクト: RIFTIO/pygobject
/**
 * 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;
}
コード例 #4
0
ファイル: pygtype.c プロジェクト: RIFTIO/pygobject
GType
pyg_type_from_object_strict(PyObject *obj, gboolean strict)
{
    PyObject *gtype;
    GType type;

    /* NULL check */
    if (!obj) {
	PyErr_SetString(PyExc_TypeError, "can't get type from NULL object");
	return 0;
    }

    /* map some standard types to primitive GTypes ... */
    if (obj == Py_None)
	return G_TYPE_NONE;
    if (PyType_Check(obj)) {
	PyTypeObject *tp = (PyTypeObject *)obj;

	if (tp == &PYGLIB_PyLong_Type)
	    return G_TYPE_INT;
	else if (tp == &PyBool_Type)
	    return G_TYPE_BOOLEAN;
	else if (tp == &PyLong_Type)
	    return G_TYPE_LONG;
	else if (tp == &PyFloat_Type)
	    return G_TYPE_DOUBLE;
	else if (tp == &PYGLIB_PyUnicode_Type)
	    return G_TYPE_STRING;
	else if (tp == &PyBaseObject_Type)
	    return PY_TYPE_OBJECT;
    }

    if (Py_TYPE(obj) == &PyGTypeWrapper_Type) {
	return ((PyGTypeWrapper *)obj)->type;
    }

    /* handle strings */
    if (PYGLIB_PyUnicode_Check(obj)) {
	gchar *name = PYGLIB_PyUnicode_AsString(obj);

	type = g_type_from_name(name);
	if (type != 0) {
	    return type;
	}
    }

    /* finally, look for a __gtype__ attribute on the object */
    gtype = PyObject_GetAttrString(obj, "__gtype__");

    if (gtype) {
	if (Py_TYPE(gtype) == &PyGTypeWrapper_Type) {
	    type = ((PyGTypeWrapper *)gtype)->type;
	    Py_DECREF(gtype);
	    return type;
	}
	Py_DECREF(gtype);
    }

    PyErr_Clear();

    /* Some API like those that take GValues can hold a python object as
     * a pointer.  This is potentially dangerous becuase everything is 
     * passed in as a PyObject so we can't actually type check it.  Only
     * fallback to PY_TYPE_OBJECT if strict checking is disabled
     */
    if (!strict)
        return PY_TYPE_OBJECT;

    PyErr_SetString(PyExc_TypeError, "could not get typecode from object");
    return 0;
}
コード例 #5
0
ファイル: pygi-error.c プロジェクト: Distrotech/pygobject
/**
 * 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;
}
コード例 #6
0
ファイル: pygtype.c プロジェクト: nzjrs/pygobject
/**
 * 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;
}