diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2014-01-04 16:31:56 -0800 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2014-01-04 17:10:29 -0800 |
commit | aaaead18e2167c2becb309f1d9ae199222c0256b (patch) | |
tree | 37713bbc05ad12134f4e7b949357c3ee16fdc096 | |
parent | 64f15961b637a7e1388bd8d2cd08f04fa20e4de4 (diff) | |
download | pygobject-aaaead18e2167c2becb309f1d9ae199222c0256b.tar.gz |
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.
-rw-r--r-- | gi/pygi-struct.c | 39 | ||||
-rw-r--r-- | 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 38f6a8ae..296c47c0 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 20602ba1..c02581cc 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() |