These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			170 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """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()
 |