[pygobject] Fix wrapping of enums: Create new Python type for each non-gtype enum.



commit 66a5784f4ab5de5b6d8d51eb4ce869fa26f6a601
Author: Laszlo Pandy <laszlok2 gmail com>
Date:   Mon Jan 17 15:43:34 2011 +0100

    Fix wrapping of enums: Create new Python type for each non-gtype enum.
    
    Previously non-gtype enums used the same class, which meant they were all the same type.
    This caused another problem that since they were all the same class, attributes from different enums were available from each other.
    
    A new test case is created to check for this bug. It requires a new enum from the GIMarshallingTests (updating gobject-introspection will be required).

 gi/module.py     |    2 +-
 gi/types.py      |    2 ++
 tests/test_gi.py |   10 ++++++++++
 3 files changed, 13 insertions(+), 1 deletions(-)
---
diff --git a/gi/module.py b/gi/module.py
index f19dfb6..fcffba3 100644
--- a/gi/module.py
+++ b/gi/module.py
@@ -106,7 +106,7 @@ class IntrospectionModule(object):
                     wrapper = enum_add(g_type)
                 elif g_type.is_a(gobject.TYPE_NONE):
                     # An enum with a GType of None is an enum without GType
-                    wrapper = Enum
+                    wrapper = type(info.get_name(), (Enum,), {'__info__': None})
                 else:
                     wrapper = flags_add(g_type)
 
diff --git a/gi/types.py b/gi/types.py
index 4f7094e..970f19c 100644
--- a/gi/types.py
+++ b/gi/types.py
@@ -216,6 +216,8 @@ class StructMeta(type, MetaClassHelper):
         cls._setup_constructors()
 
 class Enum(int):
+    # Subclasses should have their own __info__ attribute
+    # so that all Enums do not share the same gi type.
     __info__ = None
     def __init__(self, value):
         int.__init__(value)
diff --git a/tests/test_gi.py b/tests/test_gi.py
index e19b7fd..3121a68 100644
--- a/tests/test_gi.py
+++ b/tests/test_gi.py
@@ -967,6 +967,16 @@ class TestEnum(unittest.TestCase):
         self.assertTrue(isinstance(enum, GIMarshallingTests.Enum))
         self.assertEquals(enum, GIMarshallingTests.Enum.VALUE1)
 
+    def test_enum_second(self):
+        # check for the bug where different non-gtype enums share the same class
+        self.assertNotEqual(GIMarshallingTests.Enum, GIMarshallingTests.SecondEnum)
+
+        # check that values are not being shared between different enums
+        self.assertTrue(hasattr(GIMarshallingTests.SecondEnum, "SECONDVALUE1"))
+        self.assertRaises(AttributeError, getattr, GIMarshallingTests.Enum, "SECONDVALUE1")
+        self.assertTrue(hasattr(GIMarshallingTests.Enum, "VALUE1"))
+        self.assertRaises(AttributeError, getattr, GIMarshallingTests.SecondEnum, "VALUE1")
+
 
 class TestGEnum(unittest.TestCase):
 



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