symbian-qemu-0.9.1-12/python-2.6.1/Demo/metaclasses/Enum.py
changeset 1 2fb8b9db1c86
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symbian-qemu-0.9.1-12/python-2.6.1/Demo/metaclasses/Enum.py	Fri Jul 31 15:01:17 2009 +0100
@@ -0,0 +1,169 @@
+"""Enumeration metaclass.
+
+XXX This is very much a work in progress.
+
+"""
+
+import string
+
+class EnumMetaClass:
+    """Metaclass for enumeration.
+
+    To define your own enumeration, do something like
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    Now, Color.red, Color.green and Color.blue behave totally
+    different: they are enumerated values, not integers.
+
+    Enumerations cannot be instantiated; however they can be
+    subclassed.
+
+    """
+
+    def __init__(self, name, bases, dict):
+        """Constructor -- create an enumeration.
+
+        Called at the end of the class statement.  The arguments are
+        the name of the new class, a tuple containing the base
+        classes, and a dictionary containing everything that was
+        entered in the class' namespace during execution of the class
+        statement.  In the above example, it would be {'red': 1,
+        'green': 2, 'blue': 3}.
+
+        """
+        for base in bases:
+            if base.__class__ is not EnumMetaClass:
+                raise TypeError, "Enumeration base class must be enumeration"
+        bases = filter(lambda x: x is not Enum, bases)
+        self.__name__ = name
+        self.__bases__ = bases
+        self.__dict = {}
+        for key, value in dict.items():
+            self.__dict[key] = EnumInstance(name, key, value)
+
+    def __getattr__(self, name):
+        """Return an enumeration value.
+
+        For example, Color.red returns the value corresponding to red.
+
+        XXX Perhaps the values should be created in the constructor?
+
+        This looks in the class dictionary and if it is not found
+        there asks the base classes.
+
+        The special attribute __members__ returns the list of names
+        defined in this class (it does not merge in the names defined
+        in base classes).
+
+        """
+        if name == '__members__':
+            return self.__dict.keys()
+
+        try:
+            return self.__dict[name]
+        except KeyError:
+            for base in self.__bases__:
+                try:
+                    return getattr(base, name)
+                except AttributeError:
+                    continue
+
+        raise AttributeError, name
+
+    def __repr__(self):
+        s = self.__name__
+        if self.__bases__:
+            s = s + '(' + string.join(map(lambda x: x.__name__,
+                                          self.__bases__), ", ") + ')'
+        if self.__dict:
+            list = []
+            for key, value in self.__dict.items():
+                list.append("%s: %s" % (key, int(value)))
+            s = "%s: {%s}" % (s, string.join(list, ", "))
+        return s
+
+
+class EnumInstance:
+    """Class to represent an enumeration value.
+
+    EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
+    like the integer 12 when compared, but doesn't support arithmetic.
+
+    XXX Should it record the actual enumeration rather than just its
+    name?
+
+    """
+
+    def __init__(self, classname, enumname, value):
+        self.__classname = classname
+        self.__enumname = enumname
+        self.__value = value
+
+    def __int__(self):
+        return self.__value
+
+    def __repr__(self):
+        return "EnumInstance(%r, %r, %r)" % (self.__classname,
+                                             self.__enumname,
+                                             self.__value)
+
+    def __str__(self):
+        return "%s.%s" % (self.__classname, self.__enumname)
+
+    def __cmp__(self, other):
+        return cmp(self.__value, int(other))
+
+
+# Create the base class for enumerations.
+# It is an empty enumeration.
+Enum = EnumMetaClass("Enum", (), {})
+
+
+def _test():
+
+    class Color(Enum):
+        red = 1
+        green = 2
+        blue = 3
+
+    print Color.red
+    print dir(Color)
+
+    print Color.red == Color.red
+    print Color.red == Color.blue
+    print Color.red == 1
+    print Color.red == 2
+
+    class ExtendedColor(Color):
+        white = 0
+        orange = 4
+        yellow = 5
+        purple = 6
+        black = 7
+
+    print ExtendedColor.orange
+    print ExtendedColor.red
+
+    print Color.red == ExtendedColor.red
+
+    class OtherColor(Enum):
+        white = 4
+        blue = 5
+
+    class MergedColor(Color, OtherColor):
+        pass
+
+    print MergedColor.red
+    print MergedColor.white
+
+    print Color
+    print ExtendedColor
+    print OtherColor
+    print MergedColor
+
+if __name__ == '__main__':
+    _test()