2      """ 
  3      Minimal order preserving dictionary.  Uses a list of keys in addition 
  4      to an internal dictionary to keep track of the order in which entries are 
  5      added to the dictionary.  Calls to keys(), values(), items(), iterkeys(), 
  6      itervalues() and iteritems() and popitem() will return data in the order 
  7      that it was added to the dictionary. 
  8   
  9      This class is intended as a drop in replacement for the builtin dict type 
 10      and replicates all its methods.  While the internal representation would 
 11      enable the addition of mutable sequence methods such as slices these have 
 12      not (yet) been implemented. 
 13   
 14      The motivation for creating this class was to stop the standard library 
 15      ConfigParser module randomising the order of sections and options when 
 16      saving modified configs back to a file. 
 17   
 18      Anthony Horton 
 19      horton@ast.cam.ac.uk 
 20      20050216 
 21      """ 
 22   
 24   
 25           
 26           
 27           
 28           
 29           
 30   
 31          if kwargs and not arg: 
 32               
 33              dict.__init__(self, kwargs) 
 34              self.__keylist = dict.keys(self) 
 35          else: 
 36               
 37               
 38   
 39              if hasattr(arg, 'keys'): 
 40                   
 41                  dict.__init__(self, arg) 
 42                   
 43                  self.__keylist = arg.keys() 
 44   
 45              else: 
 46                  self.__keylist = [] 
 47                  dict.__init__({}) 
 48                   
 49                   
 50                   
 51                  for item in arg: 
 52                      self.__setitem__(*item) 
 53   
 54               
 55              if kwargs: 
 56                  self.update(kwargs) 
 57                  self.__keylist.extend(kwargs.keys()) 
  58   
 60          dict.__delitem__(self, key) 
 61          self.__keylist.remove(key) 
  62   
 64          has_key = self.has_key(key) 
 65          dict.__setitem__(self, key, value) 
 66          if not has_key: 
 67              self.__keylist.append(key) 
  68   
 71   
 73          return '{' + ', '.join(\ 
 74              [': '.join((repr(key), repr(self[key]))) for key in self.keys()]\ 
 75              ) + '}' 
  76       
 79   
 81          return self.__keylist[:] 
 82   
 84          return [self[key] for key in self.keys()] 
  85   
 87          return [(key, self[key]) for key in self.keys()] 
  88   
 90          return iter(self.keys()) 
  91   
 94   
 96          return iter(self.items()) 
  97   
 99          for key in opd: 
100              self[key] = opd[key] 
101   
102 -    def pop(self, key, default=None): 
 103          if self.has_key(key): 
104              value = self[key] 
105              del self[key] 
106              return value 
107          else: 
108              if default: 
109                  return default 
110              else: 
111                  raise KeyError(key) 
112   
114          if not self.__keylist: 
115              raise KeyError 
116          key = self.__keylist[-1] 
117          item = (key, self[key]) 
118          del self[key] 
119          return item 
120   
123   
125          dict.clear(self) 
126          self.__keylist = [] 
 127   
129          opd = opdict() 
130          for key in keys: 
131              opd[key] = value 
132          return opd 
 133   
135          try: 
136              return self[key] 
137          except KeyError: 
138              self[key] = default 
139              return default 
 140