[pygobject] gerror: Add special case marshaling for boxing GErrors
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] gerror: Add special case marshaling for boxing GErrors
- Date: Wed, 2 Mar 2016 05:08:26 +0000 (UTC)
commit 5f4b08f4e8a98046eab71537c7827edde2ca8742
Author: Simon Feltman <sfeltman src gnome org>
Date: Mon Feb 29 22:50:32 2016 -0800
gerror: Add special case marshaling for boxing GErrors
Transfer gtype from introspection GError class to Python GError implementation.
Expose the PyGError pointer as an extern so other C files can pick this up.
Add custom to/from GValue marshalers for GError.
Add tests for both complete and incomplete (no boxed pointer held).
https://bugzilla.gnome.org/show_bug.cgi?id=761592
gi/overrides/GLib.py | 1 +
gi/pygi-error.c | 32 +++++++++++++++++++++++++++++++-
gi/pygi-error.h | 2 ++
gi/pygi-value.c | 1 +
tests/test_gobject.py | 17 +++++++++++++++++
5 files changed, 52 insertions(+), 1 deletions(-)
---
diff --git a/gi/overrides/GLib.py b/gi/overrides/GLib.py
index 455ea84..c12b4d8 100644
--- a/gi/overrides/GLib.py
+++ b/gi/overrides/GLib.py
@@ -74,6 +74,7 @@ def gerror_new_literal(domain, message, code):
# Monkey patch methods that rely on GLib introspection to be loaded at runtime.
Error.__name__ = 'Error'
Error.__module__ = 'GLib'
+Error.__gtype__ = GLib.Error.__gtype__
Error.matches = gerror_matches
Error.new_literal = staticmethod(gerror_new_literal)
diff --git a/gi/pygi-error.c b/gi/pygi-error.c
index 9a9a10d..d86021c 100644
--- a/gi/pygi-error.c
+++ b/gi/pygi-error.c
@@ -23,9 +23,10 @@
#include "pyglib.h"
#include "pygi-private.h"
#include "pygi-error.h"
+#include "pygtype.h"
-static PyObject *PyGError = NULL;
+PyObject *PyGError = NULL;
static PyObject *exception_table = NULL;
/**
@@ -346,6 +347,31 @@ pygi_arg_gerror_new_from_info (GITypeInfo *type_info,
}
}
+static PyObject *
+pygerror_from_gvalue (const GValue *value)
+{
+ GError *gerror = (GError *) g_value_get_boxed (value);
+ PyObject *pyerr = pygi_error_marshal_to_py (&gerror);
+ if (pyerr == NULL) {
+ Py_RETURN_NONE;
+ } else {
+ return pyerr;
+ }
+}
+
+static int
+pygerror_to_gvalue (GValue *value, PyObject *pyerror)
+{
+ GError *gerror = NULL;
+
+ if (pygi_error_marshal_from_py (pyerror, &gerror)) {
+ g_value_take_boxed (value, gerror);
+ return 0;
+ }
+
+ return -1;
+}
+
void
pygi_error_register_types (PyObject *module)
{
@@ -356,5 +382,9 @@ pygi_error_register_types (PyObject *module)
/* Stash a reference to the Python implemented gi._error.GError. */
PyGError = PyObject_GetAttrString (error_module, "GError");
+
+ pyg_register_gtype_custom (G_TYPE_ERROR,
+ pygerror_from_gvalue,
+ pygerror_to_gvalue);
}
diff --git a/gi/pygi-error.h b/gi/pygi-error.h
index 378c1b4..e7cc05f 100644
--- a/gi/pygi-error.h
+++ b/gi/pygi-error.h
@@ -27,6 +27,8 @@
G_BEGIN_DECLS
+extern PyObject *PyGError;
+
gboolean pygi_error_check (GError **error);
PyObject* pygi_error_marshal_to_py (GError **error);
diff --git a/gi/pygi-value.c b/gi/pygi-value.c
index b155a68..9da87a5 100644
--- a/gi/pygi-value.c
+++ b/gi/pygi-value.c
@@ -874,6 +874,7 @@ pyg_value_as_pyobject (const GValue *value, gboolean copy_boxed)
}
return NULL;
+
}
diff --git a/tests/test_gobject.py b/tests/test_gobject.py
index 87b0e4c..e78132d 100644
--- a/tests/test_gobject.py
+++ b/tests/test_gobject.py
@@ -675,5 +675,22 @@ class TestGValue(unittest.TestCase):
value.set_value([32, 'foo_bar', 0.3])
self.assertEqual(value.get_value(), [32, 'foo_bar', 0.3])
+ def test_gerror_boxing(self):
+ error = GLib.Error('test message', domain='mydomain', code=42)
+ value = GObject.Value(GLib.Error, error)
+ self.assertEqual(value.g_type, GObject.type_from_name('GError'))
+
+ unboxed = value.get_value()
+ self.assertEqual(unboxed.message, error.message)
+ self.assertEqual(unboxed.domain, error.domain)
+ self.assertEqual(unboxed.code, error.code)
+
+ def test_gerror_novalue(self):
+ error = GLib.Error('test message', domain='mydomain', code=42)
+ value = GObject.Value(GLib.Error)
+ self.assertEqual(value.g_type, GObject.type_from_name('GError'))
+ self.assertEqual(value.get_value(), None)
+
+
if __name__ == '__main__':
unittest.main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]