config.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import ConfigParser
  2. class OrderedRawConfigParser( ConfigParser.RawConfigParser ):
  3. """
  4. Overload standard Class ConfigParser.RawConfigParser
  5. """
  6. def write(self, fp):
  7. """Write an .ini-format representation of the configuration state."""
  8. if self._defaults:
  9. fp.write("[%s]\n" % DEFAULTSECT)
  10. for key in sorted( self._defaults ):
  11. fp.write( "%s = %s\n" % (key, str( self._defaults[ key ]
  12. ).replace('\n', '\n\t')) )
  13. fp.write("\n")
  14. for section in self._sections:
  15. fp.write("[%s]\n" % section)
  16. for key in sorted( self._sections[section] ):
  17. if key != "__name__":
  18. fp.write("%s = %s\n" %
  19. (key, str( self._sections[section][ key ]
  20. ).replace('\n', '\n\t')))
  21. fp.write("\n")
  22. optionxform = str
  23. _NOTFOUND = object()
  24. class Flipdict(dict):
  25. """An injective (one-to-one) python dict. Ensures that each key maps
  26. to a unique value, and each value maps back to that same key.
  27. Code mostly taken from here:
  28. http://code.activestate.com/recipes/576968-flipdict-python-dict-that-also-maintains-a-one-to-/
  29. """
  30. def __init__(self, *args, **kw):
  31. self._flip = dict.__new__(self.__class__)
  32. setattr(self._flip, "_flip", self)
  33. for key, val in dict(*args, **kw).iteritems():
  34. self[key] = val
  35. @property
  36. def flip(self):
  37. """The inverse mapping."""
  38. return self._flip
  39. def __repr__(self):
  40. return "%s(%r)" % (self.__class__.__name__, dict(self))
  41. __str__ = __repr__
  42. def copy(self):
  43. return self.__class__(self)
  44. @classmethod
  45. def fromkeys(cls, keys, value=None):
  46. return cls(dict.fromkeys(keys, value))
  47. def __setitem__(self, key, val):
  48. k = self._flip.get(val, _NOTFOUND)
  49. if not (k is _NOTFOUND or k==key):
  50. raise KeyError('(key,val) would erase mapping for value %r' % val)
  51. v = self.get(key, _NOTFOUND)
  52. if v is not _NOTFOUND:
  53. dict.__delitem__(self._flip, v)
  54. dict.__setitem__(self, key, val)
  55. dict.__setitem__(self._flip, val, key)
  56. def setdefault(self, key, default = None):
  57. # Copied from python's UserDict.DictMixin code.
  58. try:
  59. return self[key]
  60. except KeyError:
  61. self[key] = default
  62. return default
  63. def update(self, other = None, **kwargs):
  64. # Copied from python's UserDict.DictMixin code.
  65. # Make progressively weaker assumptions about "other"
  66. if other is None:
  67. pass
  68. elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups
  69. for k, v in other.iteritems():
  70. self[k] = v
  71. elif hasattr(other, 'keys'):
  72. for k in other.keys():
  73. self[k] = other[k]
  74. else:
  75. for k, v in other:
  76. self[k] = v
  77. if kwargs:
  78. self.update(kwargs)
  79. def __delitem__(self, key):
  80. val = dict.pop(self, key)
  81. dict.__delitem__(self._flip, val)
  82. def pop(self, key, *args):
  83. val = dict.pop(self, key, *args)
  84. dict.__delitem__(self._flip, val)
  85. return val
  86. def popitem(self):
  87. key, val = dict.popitem(self)
  88. dict.__delitem__(self._flip, val)
  89. return key, val
  90. def clear(self):
  91. dict.clear(self)
  92. dict.clear(self._flip)