[pygobject] Support union creation with PyGIStruct
- From: Simon Feltman <sfeltman src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Support union creation with PyGIStruct
- Date: Sun, 5 Jan 2014 01:14:29 +0000 (UTC)
commit aaaead18e2167c2becb309f1d9ae199222c0256b
Author: Simon Feltman <sfeltman src gnome org>
Date: Sat Jan 4 16:31:56 2014 -0800
Support union creation with PyGIStruct
Add additional case for allowing the creation bare unions wrapped with
PyGIStruct. This is needed because PyGIStruct wraps both GIStruct and
GIUnion types.
gi/pygi-struct.c | 39 ++++++++++++++++++++++++++++++++++-----
tests/test_repository.py | 13 +++++++++++++
2 files changed, 47 insertions(+), 5 deletions(-)
---
diff --git a/gi/pygi-struct.c b/gi/pygi-struct.c
index 38f6a8a..296c47c 100644
--- a/gi/pygi-struct.c
+++ b/gi/pygi-struct.c
@@ -27,12 +27,39 @@
#include <girepository.h>
#include <pyglib-python-compat.h>
+
+static GIBaseInfo *
+_struct_get_info (PyObject *self)
+{
+ PyObject *py_info;
+ GIBaseInfo *info = NULL;
+
+ py_info = PyObject_GetAttrString (self, "__info__");
+ if (py_info == NULL) {
+ return NULL;
+ }
+ if (!PyObject_TypeCheck (py_info, &PyGIStructInfo_Type) &&
+ !PyObject_TypeCheck (py_info, &PyGIUnionInfo_Type)) {
+ PyErr_Format (PyExc_TypeError, "attribute '__info__' must be %s or %s, not %s",
+ PyGIStructInfo_Type.tp_name,
+ PyGIUnionInfo_Type.tp_name,
+ Py_TYPE(py_info)->tp_name);
+ goto out;
+ }
+
+ info = ( (PyGIBaseInfo *) py_info)->info;
+ g_base_info_ref (info);
+
+out:
+ Py_DECREF (py_info);
+
+ return info;
+}
+
static void
_struct_dealloc (PyGIStruct *self)
{
- GIBaseInfo *info = _pygi_object_get_gi_info (
- (PyObject *) self,
- &PyGIStructInfo_Type);
+ GIBaseInfo *info = _struct_get_info ( (PyObject *) self );
if (info != NULL && g_struct_info_is_foreign ( (GIStructInfo *) info)) {
pygi_struct_foreign_release (info, ( (PyGPointer *) self)->pointer);
@@ -40,7 +67,9 @@ _struct_dealloc (PyGIStruct *self)
g_free ( ( (PyGPointer *) self)->pointer);
}
- g_base_info_unref (info);
+ if (info != NULL) {
+ g_base_info_unref (info);
+ }
Py_TYPE( (PyGPointer *) self )->tp_free ( (PyObject *) self);
}
@@ -61,7 +90,7 @@ _struct_new (PyTypeObject *type,
return NULL;
}
- info = _pygi_object_get_gi_info ( (PyObject *) type, &PyGIStructInfo_Type);
+ info = _struct_get_info ( (PyObject *) type );
if (info == NULL) {
if (PyErr_ExceptionMatches (PyExc_AttributeError)) {
PyErr_Format (PyExc_TypeError, "missing introspection information");
diff --git a/tests/test_repository.py b/tests/test_repository.py
index 20602ba..c02581c 100644
--- a/tests/test_repository.py
+++ b/tests/test_repository.py
@@ -28,6 +28,7 @@ from gi.module import repository as repo
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import GIMarshallingTests
+from gi.repository import GIRepository as IntrospectedRepository
try:
import cairo
@@ -338,6 +339,18 @@ class Test(unittest.TestCase):
self.assertTrue(hasattr(GIRepository, 'TypeTag'))
self.assertTrue(hasattr(GIRepository, 'InfoType'))
+ def test_introspected_argument_info(self):
+ self.assertTrue(isinstance(IntrospectedRepository.Argument.__info__,
+ GIRepository.UnionInfo))
+
+ arg = IntrospectedRepository.Argument()
+ self.assertTrue(isinstance(arg.__info__, GIRepository.UnionInfo))
+
+ old_info = IntrospectedRepository.Argument.__info__
+ IntrospectedRepository.Argument.__info__ = 'not an info'
+ self.assertRaises(TypeError, IntrospectedRepository.Argument)
+ IntrospectedRepository.Argument.__info__ = old_info
+
if __name__ == '__main__':
unittest.main()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]