Package translate :: Package misc :: Module dictutils
[hide private]
[frames] | no frames]

Source Code for Module translate.misc.dictutils

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  """Implements a case-insensitive (on keys) dictionary and order-sensitive dictionary""" 
  5   
  6  # Copyright 2002, 2003 St James Software 
  7  # 
  8  # This file is part of translate. 
  9  # 
 10  # translate is free software; you can redistribute it and/or modify 
 11  # it under the terms of the GNU General Public License as published by 
 12  # the Free Software Foundation; either version 2 of the License, or 
 13  # (at your option) any later version. 
 14  # 
 15  # translate is distributed in the hope that it will be useful, 
 16  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 18  # GNU General Public License for more details. 
 19  # 
 20  # You should have received a copy of the GNU General Public License 
 21  # along with translate; if not, write to the Free Software 
 22  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 23   
 24   
25 -def generalupper(str):
26 """this uses the object's upper method - works with string and unicode""" 27 if str is None: 28 return str 29 return str.upper()
30 31
32 -class cidict(dict):
33
34 - def __init__(self, fromdict=None):
35 """constructs the cidict, optionally using another dict to do so""" 36 if fromdict is not None: 37 self.update(fromdict)
38
39 - def __getitem__(self, key):
40 if type(key) != str and type(key) != unicode: 41 raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key)) 42 for akey in self.iterkeys(): 43 if akey.lower() == key.lower(): 44 return dict.__getitem__(self, akey) 45 raise IndexError
46
47 - def __setitem__(self, key, value):
48 if type(key) != str and type(key) != unicode: 49 raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key)) 50 for akey in self.iterkeys(): 51 if akey.lower() == key.lower(): 52 return dict.__setitem__(self, akey, value) 53 return dict.__setitem__(self, key, value)
54
55 - def update(self, updatedict):
56 """D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]""" 57 for key, value in updatedict.iteritems(): 58 self[key] = value
59
60 - def __delitem__(self, key):
61 if type(key) != str and type(key) != unicode: 62 raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key)) 63 for akey in self.iterkeys(): 64 if akey.lower() == key.lower(): 65 return dict.__delitem__(self, akey) 66 raise IndexError
67
68 - def __contains__(self, key):
69 if type(key) != str and type(key) != unicode: 70 raise TypeError("cidict can only have str or unicode as key (got %r)" % type(key)) 71 for akey in self.iterkeys(): 72 if akey.lower() == key.lower(): 73 return 1 74 return 0
75
76 - def has_key(self, key):
77 return self.__contains__(key)
78
79 - def get(self, key, default=None):
80 if self.has_key(key): 81 return self[key] 82 else: 83 return default
84 85
86 -class ordereddict(dict):
87 """a dictionary which remembers its keys in the order in which they were given""" 88
89 - def __init__(self, *args):
90 if len(args) == 0: 91 super(ordereddict, self).__init__() 92 self.order = [] 93 elif len(args) > 1: 94 raise TypeError("ordereddict() takes at most 1 argument (%d given)" % len(args)) 95 else: 96 initarg = args[0] 97 apply(super(ordereddict, self).__init__, args) 98 if hasattr(initarg, "keys"): 99 self.order = initarg.keys() 100 else: 101 # danger: could have duplicate keys... 102 self.order = [] 103 checkduplicates = {} 104 for key, value in initarg: 105 if not key in checkduplicates: 106 self.order.append(key) 107 checkduplicates[key] = None
108
109 - def __setitem__(self, key, value):
110 alreadypresent = key in self 111 result = dict.__setitem__(self, key, value) 112 if not alreadypresent: 113 self.order.append(key) 114 return result
115
116 - def update(self, updatedict):
117 """D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]""" 118 for key, value in updatedict.iteritems(): 119 self[key] = value
120
121 - def __delitem__(self, key):
122 alreadypresent = key in self 123 result = dict.__delitem__(self, key) 124 if alreadypresent: 125 del self.order[self.order.index(key)] 126 return result
127
128 - def copy(self):
129 """D.copy() -> a shallow copy of D""" 130 thecopy = ordereddict(super(ordereddict, self).copy()) 131 thecopy.order = self.order[:] 132 return thecopy
133
134 - def items(self):
135 """D.items() -> list of D's (key, value) pairs, as 2-tuples""" 136 return [(key, self[key]) for key in self.order]
137
138 - def iteritems(self):
139 """D.iteritems() -> an iterator over the (key, value) items of D""" 140 for key in self.order: 141 yield (key, self[key])
142
143 - def iterkeys(self):
144 """D.iterkeys() -> an iterator over the keys of D""" 145 for key in self.order: 146 yield key
147 148 __iter__ = iterkeys 149
150 - def itervalues(self):
151 """D.itervalues() -> an iterator over the values of D""" 152 for key in self.order: 153 yield self[key]
154
155 - def keys(self):
156 """D.keys() -> list of D's keys""" 157 return self.order[:]
158
159 - def popitem(self):
160 """D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty""" 161 if len(self.order) == 0: 162 raise KeyError("popitem(): ordered dictionary is empty") 163 k = self.order.pop() 164 v = self[k] 165 del self[k] 166 return (k, v)
167
168 - def pop(self, key):
169 """remove entry from dict and internal list""" 170 value = super(ordereddict, self).pop(key) 171 del self.order[self.order.index(key)] 172 return value
173