[pygobject] Refactor pyg_value_from_pyobject into two functions
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Refactor pyg_value_from_pyobject into two functions
- Date: Thu, 25 Jul 2013 20:01:05 +0000 (UTC)
commit 2cff4827e6d15bcad630316a8a4e67968a70bbbf
Author: Simon Feltman <sfeltman src gnome org>
Date: Sat Jul 6 14:10:20 2013 -0700
Refactor pyg_value_from_pyobject into two functions
Break pyg_value_from_pyobject into two functions. One which keeps
Python exceptions queued (pyg_value_from_pyobject_with_error) and
one which clears them (pyg_value_from_pyobject). This allows for
re-use for code which want to keep the errors around
https://bugzilla.gnome.org/show_bug.cgi?id=688081
gi/_gobject/gobjectmodule.c | 4 ++-
gi/_gobject/pygobject-private.h | 1 +
gi/_gobject/pygobject.h | 2 +
gi/_gobject/pygtype.c | 67 ++++++++++++++++++++++++++++++--------
4 files changed, 59 insertions(+), 15 deletions(-)
---
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index 81dc44b..736cd8c 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -2072,7 +2072,9 @@ struct _PyGObject_Functions pygobject_api_functions = {
pyg_type_from_object_strict,
pygobject_new_full,
- &PyGObject_Type
+ &PyGObject_Type,
+
+ pyg_value_from_pyobject_with_error
};
/* for addon libraries ... */
diff --git a/gi/_gobject/pygobject-private.h b/gi/_gobject/pygobject-private.h
index e2a0af7..294b0f6 100644
--- a/gi/_gobject/pygobject-private.h
+++ b/gi/_gobject/pygobject-private.h
@@ -85,6 +85,7 @@ void pyg_register_gtype_custom(GType gtype,
fromvaluefunc from_func,
tovaluefunc to_func);
int pyg_value_from_pyobject(GValue *value, PyObject *obj);
+int pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj);
PyObject *pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed);
int pyg_param_gvalue_from_pyobject(GValue* value,
PyObject* py_obj,
diff --git a/gi/_gobject/pygobject.h b/gi/_gobject/pygobject.h
index f6b531d..76b8b11 100644
--- a/gi/_gobject/pygobject.h
+++ b/gi/_gobject/pygobject.h
@@ -195,6 +195,7 @@ struct _PyGObject_Functions {
PyObject *(* newgobj_full)(GObject *obj, gboolean steal, gpointer g_class);
PyTypeObject *object_type;
+ int (* value_from_pyobject_with_error)(GValue *value, PyObject *obj);
};
@@ -244,6 +245,7 @@ struct _PyGObject_Functions *_PyGObject_API;
#define pyg_flags_get_value (_PyGObject_API->flags_get_value)
#define pyg_register_gtype_custom (_PyGObject_API->register_gtype_custom)
#define pyg_value_from_pyobject (_PyGObject_API->value_from_pyobject)
+#define pyg_value_from_pyobject_with_error (_PyGObject_API->value_from_pyobject_with_error)
#define pyg_value_as_pyobject (_PyGObject_API->value_as_pyobject)
#define pyg_register_interface (_PyGObject_API->register_interface)
#define PyGBoxed_Type (*_PyGObject_API->boxed_type)
diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c
index 3f3f048..0b920f6 100644
--- a/gi/_gobject/pygtype.c
+++ b/gi/_gobject/pygtype.c
@@ -785,7 +785,7 @@ pyg_array_from_pyobject(GValue *value,
}
/**
- * pyg_value_from_pyobject:
+ * pyg_value_from_pyobject_with_error:
* @value: the GValue object to store the converted value in.
* @obj: the Python object to convert.
*
@@ -797,7 +797,7 @@ pyg_array_from_pyobject(GValue *value,
* Returns: 0 on success, -1 on error.
*/
int
-pyg_value_from_pyobject(GValue *value, PyObject *obj)
+pyg_value_from_pyobject_with_error(GValue *value, PyObject *obj)
{
PyObject *tmp;
GType value_type = G_VALUE_TYPE(value);
@@ -810,15 +810,18 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_object(value, NULL);
else {
if (!PyObject_TypeCheck(obj, &PyGObject_Type)) {
+ PyErr_SetString(PyExc_TypeError, "GObject is required");
return -1;
}
if (!G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
value_type)) {
+ PyErr_SetString(PyExc_TypeError, "Invalid GObject type for assignment");
return -1;
}
g_value_set_object(value, pygobject_get(obj));
}
} else {
+ PyErr_SetString(PyExc_TypeError, "Unsupported conversion");
return -1;
}
break;
@@ -841,7 +844,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_schar(value, PYGLIB_PyBytes_AsString(tmp)[0]);
Py_DECREF(tmp);
} else {
- PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError, "Cannot convert to TYPE_CHAR");
return -1;
}
@@ -936,7 +939,6 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
{
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);
@@ -946,7 +948,6 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
{
guint val = 0;
if (pyg_flags_get_value(G_VALUE_TYPE(value), obj, &val) < 0) {
- PyErr_Clear();
return -1;
}
g_value_set_flags(value, val);
@@ -970,6 +971,7 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_string(value, PYGLIB_PyBytes_AsString(tmp));
Py_DECREF(tmp);
} else {
+ PyErr_SetString(PyExc_TypeError, "Expected string");
return -1;
}
} else {
@@ -994,8 +996,10 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_pointer(value, PYGLIB_CPointer_GetPointer(obj, NULL));
else if (G_VALUE_HOLDS_GTYPE (value))
g_value_set_gtype (value, pyg_type_from_object (obj));
- else
+ else {
+ PyErr_SetString(PyExc_TypeError, "Expected pointer");
return -1;
+ }
break;
case G_TYPE_BOXED: {
PyGTypeMarshal *bm;
@@ -1013,13 +1017,12 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
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);
+ return pyg_value_from_pyobject_with_error (n_value, obj);
}
else if (PySequence_Check(obj) &&
G_VALUE_HOLDS(value, G_TYPE_VALUE_ARRAY))
@@ -1043,8 +1046,10 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
return bm->tovalue(value, obj);
else if (PYGLIB_CPointer_Check(obj))
g_value_set_boxed(value, PYGLIB_CPointer_GetPointer(obj, NULL));
- else
+ else {
+ PyErr_SetString(PyExc_TypeError, "Expected Boxed");
return -1;
+ }
break;
}
case G_TYPE_PARAM:
@@ -1054,8 +1059,10 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_param(value, G_PARAM_SPEC (pygobject_get (obj)));
else if (PyGParamSpec_Check(obj))
g_value_set_param(value, PYGLIB_CPointer_GetPointer(obj, NULL));
- else
+ else {
+ PyErr_SetString(PyExc_TypeError, "Expected ParamSpec");
return -1;
+ }
break;
case G_TYPE_OBJECT:
if (obj == Py_None) {
@@ -1064,8 +1071,10 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
G_TYPE_CHECK_INSTANCE_TYPE(pygobject_get(obj),
G_VALUE_TYPE(value))) {
g_value_set_object(value, pygobject_get(obj));
- } else
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Expected GObject");
return -1;
+ }
break;
case G_TYPE_VARIANT:
{
@@ -1073,27 +1082,57 @@ pyg_value_from_pyobject(GValue *value, PyObject *obj)
g_value_set_variant(value, NULL);
else if (pyg_type_from_object_strict(obj, FALSE) == G_TYPE_VARIANT)
g_value_set_variant(value, pyg_boxed_get(obj, GVariant));
- else
+ else {
+ PyErr_SetString(PyExc_TypeError, "Expected Variant");
return -1;
+ }
break;
}
default:
{
PyGTypeMarshal *bm;
- if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL)
+ if ((bm = pyg_type_lookup(G_VALUE_TYPE(value))) != NULL) {
return bm->tovalue(value, obj);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Unknown value type");
+ return -1;
+ }
break;
}
}
+
+ /* If an error occurred, unset the GValue but don't clear the Python error. */
if (PyErr_Occurred()) {
g_value_unset(value);
- PyErr_Clear();
return -1;
}
+
return 0;
}
/**
+ * pyg_value_from_pyobject:
+ * @value: the GValue object to store the converted value in.
+ * @obj: the Python object to convert.
+ *
+ * Same basic function as pyg_value_from_pyobject_with_error but clears
+ * any Python errors before returning.
+ *
+ * Returns: 0 on success, -1 on error.
+ */
+int
+pyg_value_from_pyobject(GValue *value, PyObject *obj)
+{
+ int res = pyg_value_from_pyobject_with_error (value, obj);
+
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ return -1;
+ }
+ return res;
+}
+
+/**
* pyg_value_as_pyobject:
* @value: the GValue object.
* @copy_boxed: true if boxed values should be copied.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]