コード例 #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
ファイル: pyglib.c プロジェクト: dieterv/pygobject
void
pyglib_init(void)
{
    PyObject *glib, *cobject;
    
    glib = PyImport_ImportModule("gi._glib");
    if (!glib) {
	if (PyErr_Occurred()) {
	    PyObject *type, *value, *traceback;
	    PyObject *py_orig_exc;
	    PyErr_Fetch(&type, &value, &traceback);
	    py_orig_exc = PyObject_Repr(value);
	    Py_XDECREF(type);
	    Py_XDECREF(value);
	    Py_XDECREF(traceback);
	    PyErr_Format(PyExc_ImportError,
			 "could not import gi._glib (error was: %s)",
			 PYGLIB_PyUnicode_AsString(py_orig_exc));
	    Py_DECREF(py_orig_exc);
        } else {
	    PyErr_SetString(PyExc_ImportError,
			    "could not import gi._glib (no error given)");
	}
	return;
    }
    
    cobject = PyObject_GetAttrString(glib, "_PyGLib_API");
    if (cobject && PYGLIB_CPointer_Check(cobject))
	_PyGLib_API = (struct _PyGLib_Functions *) PYGLIB_CPointer_GetPointer(cobject, "gi._glib._PyGLib_API");
    else {
	PyErr_SetString(PyExc_ImportError,
			"could not import gi._glib (could not find _PyGLib_API object)");
	Py_DECREF(glib);
	return;
    }
}
コード例 #4
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;
}
コード例 #5
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;
}
コード例 #6
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;
}