""" ConstantMap - generate inverted maps for files of magic numbers You occasionally encounter Python modules that are little more than collections of constants. The now defunct ERRNO.py is such a module. It looks like # Generated by h2py from /usr/include/sys/errno.h # Included from standards.h __KBASE = 1000 __IRIXBASE = 1000 EPERM = 1 ENOENT = 2 ESRCH = 3 EINTR = 4 EIO = 5 ... Such modules are convenient because you can generate them automatically using h2py and not have to maintain them manually. Unfortunately, it's tedious to interpret these magic numbers when debugging, as all you have is a number. The ConstantMap class solves this problem by making it easy to generate an inverted map that maps the constant values to their names. Consider a file that contains constants representing some common names and colors: import ConstantMap mapper = ConstantMap.ConstantMap() Sally = 0 Bruce = 1 Peggy = 2 Marty = 3 NameMap = mapper.make(globals()) Cyan, Magenta, Yellow = range(3) ColorMap = mapper.make(globals()) print NameMap(0) print ColorMap(2) del ConstantMap, mapper The output of executing this script would be Sally Yellow When ConstantMap is instantiated it creates an empty map. Each time its make() method is called it is passed a current copy of globals(). It creates a new ConstantMap instance which contains any symbols it finds in globals() that are not in its map. It then updates itself from the passed in globals() and returns the new instance. """ class ConstantMap: def __init__(self, markdict=None): """add new global symbols to instance's name map""" self.names = {} self.markdict = markdict or {} def __call__(self, key): """return a specific name mapping""" return self.names[key] def clear(): """clear the mark dictionary""" self.markdict.clear() def make(self, globals): """generate and return a new map the new map contains symbols added since the last call to make symbols starting with '__' or values that are modules, instances or classes are not added to the map. """ import types newmapper = ConstantMap(self.markdict) for key,val in globals.items(): if (not newmapper.markdict.has_key(key) and key[:2] != "__" and type(val) not in [types.ModuleType, types.InstanceType, types.ClassType]): newmapper.names[val] = key self.markdict.update(globals) return newmapper