gboolean
_pyglib_handler_marshal(gpointer user_data)
{
    PyObject *tuple, *ret;
    gboolean res;
    PyGILState_STATE state;

    g_return_val_if_fail(user_data != NULL, FALSE);

    state = pyglib_gil_state_ensure();

    tuple = (PyObject *)user_data;
    ret = PyObject_CallObject(PyTuple_GetItem(tuple, 0),
			      PyTuple_GetItem(tuple, 1));
    if (!ret) {
	PyErr_Print();
	res = FALSE;
    } else {
	res = PyObject_IsTrue(ret);
	Py_DECREF(ret);
    }
    
    pyglib_gil_state_release(state);

    return res;
}
static gboolean
pyg_signal_watch_check(GSource *source)
{
    PyGILState_STATE state;
    GMainLoop *main_loop;

#ifdef HAVE_PYSIGNAL_SETWAKEUPFD
    PySignalWatchSource *real_source = (PySignalWatchSource *)source;
    GPollFD *poll_fd = &real_source->fd;
    unsigned char dummy;
    if (poll_fd->revents & G_IO_IN)
	read(poll_fd->fd, &dummy, 1);
#endif

    state = pyglib_gil_state_ensure();

    main_loop = pyg_get_current_main_loop();

    if (PyErr_CheckSignals() == -1 && main_loop != NULL) {
	PyErr_SetNone(PyExc_KeyboardInterrupt);
	g_main_loop_quit(main_loop);
    }

    pyglib_gil_state_release(state);

    return FALSE;
}
/**
 * pyglib_error_check:
 * @error: a pointer to the GError.
 *
 * Checks to see if the GError has been set.  If the error has been
 * set, then the glib.GError Python exception will be raised, and
 * the GError cleared.
 *
 * Returns: True if an error was set.
 */
gboolean
pyglib_error_check(GError **error)
{
    PyGILState_STATE state;
    PyObject *exc_type;
    PyObject *exc_instance;
    PyObject *d;

    g_return_val_if_fail(error != NULL, FALSE);

    if (*error == NULL)
	return FALSE;
    
    state = pyglib_gil_state_ensure();

    exc_type = _PyGLib_API->gerror_exception;
    if (exception_table != NULL)
    {
	PyObject *item;
	item = PyDict_GetItem(exception_table, _PyLong_FromLong((*error)->domain));
	if (item != NULL)
	    exc_type = item;
    }

    exc_instance = PyObject_CallFunction(exc_type, "z", (*error)->message);

    if ((*error)->domain) {
	PyObject_SetAttrString(exc_instance, "domain",
			       d=_PyUnicode_FromString(g_quark_to_string((*error)->domain)));
	Py_DECREF(d);
    }
    else
	PyObject_SetAttrString(exc_instance, "domain", Py_None);

    PyObject_SetAttrString(exc_instance, "code",
			   d=_PyLong_FromLong((*error)->code));
    Py_DECREF(d);

    if ((*error)->message) {
	PyObject_SetAttrString(exc_instance, "message",
			       d=_PyUnicode_FromString((*error)->message));
	Py_DECREF(d);
    } else {
	PyObject_SetAttrString(exc_instance, "message", Py_None);
    }
    
    PyErr_SetObject(_PyGLib_API->gerror_exception, exc_instance);
    Py_DECREF(exc_instance);
    g_clear_error(error);
    
    pyglib_gil_state_release(state);
    
    return TRUE;
}
/**
 * _pyglib_destroy_notify:
 * @user_data: a PyObject pointer.
 *
 * A function that can be used as a GDestroyNotify callback that will
 * call Py_DECREF on the data.
 */
void
_pyglib_destroy_notify(gpointer user_data)
{
    PyObject *obj = (PyObject *)user_data;
    PyGILState_STATE state;

    g_return_if_fail (_PyGLib_API != NULL);

    state = pyglib_gil_state_ensure();
    Py_DECREF(obj);
    pyglib_gil_state_release(state);
}
示例#5
0
static void
pyg_closure_invalidate(gpointer data, GClosure *closure)
{
    PyGClosure *pc = (PyGClosure *)closure;
    PyGILState_STATE state;

    state = pyglib_gil_state_ensure();
    Py_XDECREF(pc->callback);
    Py_XDECREF(pc->extra_args);
    Py_XDECREF(pc->swap_data);
    pyglib_gil_state_release(state);

    pc->callback = NULL;
    pc->extra_args = NULL;
    pc->swap_data = NULL;
}
示例#6
0
/**
 * pygi_error_check:
 * @error: a pointer to the GError.
 *
 * Checks to see if the GError has been set.  If the error has been
 * set, then the glib.GError Python exception will be raised, and
 * the GError cleared.
 *
 * Returns: True if an error was set.
 */
gboolean
pygi_error_check (GError **error)
{
    PyGILState_STATE state;
    PyObject *exc_instance;

    g_return_val_if_fail(error != NULL, FALSE);
    if (*error == NULL)
        return FALSE;

    state = pyglib_gil_state_ensure();

    exc_instance = pygi_error_marshal_to_py (error);
    PyErr_SetObject(PyGError, exc_instance);
    Py_DECREF(exc_instance);
    g_clear_error(error);

    pyglib_gil_state_release(state);

    return TRUE;
}
示例#7
0
/**
 * pygi_error_marshal_to_py:
 * @error: a pointer to the GError.
 *
 * Checks to see if @error has been set.  If @error has been set, then a
 * GLib.GError Python exception object is returned (but not raised).
 *
 * Returns: a GLib.GError Python exception object, or NULL.
 */
PyObject *
pygi_error_marshal_to_py (GError **error)
{
    PyGILState_STATE state;
    PyObject *exc_type;
    PyObject *exc_instance;
    const char *domain = NULL;

    g_return_val_if_fail(error != NULL, NULL);

    if (*error == NULL)
        return NULL;

    state = pyglib_gil_state_ensure();

    exc_type = PyGError;
    if (exception_table != NULL)
    {
        PyObject *item;
        item = PyDict_GetItem(exception_table, PYGLIB_PyLong_FromLong((*error)->domain));
        if (item != NULL)
            exc_type = item;
    }

    if ((*error)->domain) {
        domain = g_quark_to_string ((*error)->domain);
    }

    exc_instance = PyObject_CallFunction (exc_type, "ssi",
                                          (*error)->message,
                                          domain,
                                          (*error)->code);

    pyglib_gil_state_release(state);

    return exc_instance;
}
示例#8
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);
}
示例#9
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);
}