[pygi] Add support for enums without GType



commit 391640b30ede50af3667b1019edb72bd79f2c68c
Author: Tomeu Vizoso <tomeu sugarlabs org>
Date:   Thu Apr 22 19:53:06 2010 +0200

    Add support for enums without GType
    
    https://bugzilla.gnome.org/show_bug.cgi?id=616520

 gi/module.py       |    6 +++++-
 gi/pygi-argument.c |   22 +++++++++++++++++++++-
 gi/types.py        |   14 ++++++++++++++
 tests/test_gi.py   |   30 ++++++++++++++++++++++++++++--
 4 files changed, 68 insertions(+), 4 deletions(-)
---
diff --git a/gi/module.py b/gi/module.py
index 61fbdfc..a56bd2e 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -41,7 +41,8 @@ from ._gi import \
 from .types import \
     GObjectMeta, \
     StructMeta, \
-    Function
+    Function, \
+    Enum
 
 repository = Repository.get_default()
 
@@ -91,6 +92,9 @@ class DynamicModule(object):
             if value is None:
                 if g_type.is_a(gobject.TYPE_ENUM):
                     value = enum_add(g_type)
+                elif g_type.is_a(gobject.TYPE_NONE):
+                    # An enum with a GType of None is an enum without GType
+                    value = Enum
                 else:
                     value = flags_add(g_type)
 
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 4bedc82..8244659 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1510,7 +1510,27 @@ _pygi_argument_to_object (GArgument  *arg,
 
                     type = g_registered_type_info_get_g_type((GIRegisteredTypeInfo *)info);
 
-                    if (info_type == GI_INFO_TYPE_ENUM) {
+                    if (type == G_TYPE_NONE) {
+                        /* An enum with a GType of None is an enum without GType */
+                        PyObject *py_type = _pygi_type_import_by_gi_info(info);
+                        PyObject *py_args = NULL;
+
+                        if (!py_type)
+                            return NULL;
+
+                        py_args = PyTuple_New(1);
+                        if (PyTuple_SetItem(py_args, 0, PyLong_FromLong(arg->v_long)) != 0) {
+                            Py_DECREF(py_args);
+                            Py_DECREF(py_type);
+                            return NULL;
+                        }
+
+                        object = PyObject_CallFunction(py_type, "l", arg->v_long);
+
+                        Py_DECREF(py_args);
+                        Py_DECREF(py_type);
+
+                    } else if (info_type == GI_INFO_TYPE_ENUM) {
                         object = pyg_enum_from_gtype(type, arg->v_long);
                     } else {
                         object = pyg_flags_from_gtype(type, arg->v_long);
diff --git a/gi/types.py b/gi/types.py
index cda1e52..21ff79e 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -148,3 +148,17 @@ def override(type_):
     if g_type != gobject.TYPE_INVALID:
         g_type.pytype = type_
     return type_
+
+class Enum(int):
+    __info__ = None
+    def __init__(self, value):
+        int.__init__(value)
+
+    def __repr__(self):
+        value_name = str(self)
+        for value_info in self.__info__.get_values():
+            if self == value_info.get_value():
+                value_name = value_info.get_name().upper()
+        return "<enum %s of type %s.%s>" % (value_name,
+                                            self.__info__.get_namespace(),
+                                            self.__info__.get_name())
diff --git a/tests/test_gi.py b/tests/test_gi.py
index 9f3c215..0930d7c 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -915,10 +915,10 @@ class TestPointer(unittest.TestCase):
         self.assertEquals(GIMarshallingTests.pointer_in_return(42), 42)
 
 
-class TestGEnum(unittest.TestCase):
+class TestEnum(unittest.TestCase):
 
     def test_enum(self):
-        self.assertTrue(issubclass(GIMarshallingTests.Enum, gobject.GEnum))
+        self.assertTrue(issubclass(GIMarshallingTests.Enum, int))
         self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE1, GIMarshallingTests.Enum))
         self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE2, GIMarshallingTests.Enum))
         self.assertTrue(isinstance(GIMarshallingTests.Enum.VALUE3, GIMarshallingTests.Enum))
@@ -941,6 +941,32 @@ class TestGEnum(unittest.TestCase):
         self.assertEquals(enum, GIMarshallingTests.Enum.VALUE1)
 
 
+class TestGEnum(unittest.TestCase):
+
+    def test_genum(self):
+        self.assertTrue(issubclass(GIMarshallingTests.GEnum, gobject.GEnum))
+        self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE1, GIMarshallingTests.GEnum))
+        self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE2, GIMarshallingTests.GEnum))
+        self.assertTrue(isinstance(GIMarshallingTests.GEnum.VALUE3, GIMarshallingTests.GEnum))
+        self.assertEquals(42, GIMarshallingTests.GEnum.VALUE3)
+
+    def test_genum_in(self):
+        GIMarshallingTests.genum_in(GIMarshallingTests.GEnum.VALUE3)
+
+        self.assertRaises(TypeError, GIMarshallingTests.genum_in, 42)
+        self.assertRaises(TypeError, GIMarshallingTests.genum_in, 'GIMarshallingTests.GEnum.VALUE3')
+
+    def test_genum_out(self):
+        genum = GIMarshallingTests.genum_out()
+        self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
+        self.assertEquals(genum, GIMarshallingTests.GEnum.VALUE3)
+
+    def test_genum_inout(self):
+        genum = GIMarshallingTests.genum_inout(GIMarshallingTests.GEnum.VALUE3)
+        self.assertTrue(isinstance(genum, GIMarshallingTests.GEnum))
+        self.assertEquals(genum, GIMarshallingTests.GEnum.VALUE1)
+
+
 class TestGFlags(unittest.TestCase):
 
     def test_flags(self):



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]