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 -def generalupper(str):
25 """this uses the object's upper method - works with string and unicode""" 26 if str is None: return str 27 return str.upper()
28
29 -class cidict(dict):
30 - def __init__(self, fromdict = None):
31 """constructs the cidict, optionally using another dict to do so""" 32 if fromdict is not None: 33 self.update(fromdict)
34
35 - def __getitem__(self, key):
36 if type(key) != str and type(key) != unicode: 37 raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key) 38 for akey in self.iterkeys(): 39 if akey.lower() == key.lower(): 40 return dict.__getitem__(self, akey) 41 raise IndexError
42
43 - def __setitem__(self, key, value):
44 if type(key) != str and type(key) != unicode: 45 raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key) 46 for akey in self.iterkeys(): 47 if akey.lower() == key.lower(): 48 return dict.__setitem__(self, akey, value) 49 return dict.__setitem__(self, key, value)
50
51 - def update(self, updatedict):
52 """D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]""" 53 for key, value in updatedict.iteritems(): 54 self[key] = value
55
56 - def __delitem__(self, key):
57 if type(key) != str and type(key) != unicode: 58 raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key) 59 for akey in self.iterkeys(): 60 if akey.lower() == key.lower(): 61 return dict.__delitem__(self, akey) 62 raise IndexError
63
64 - def __contains__(self, key):
65 if type(key) != str and type(key) != unicode: 66 raise TypeError, "cidict can only have str or unicode as key (got %r)" % type(key) 67 for akey in self.iterkeys(): 68 if akey.lower() == key.lower(): 69 return 1 70 return 0
71
72 - def has_key(self, key):
73 return self.__contains__(key)
74
75 - def get(self, key, default=None):
76 if self.has_key(key): 77 return self[key] 78 else: 79 return default
80
81 -class ordereddict(dict):
82 """a dictionary which remembers its keys in the order in which they were given"""
83 - def __init__(self, *args):
84 if len(args) == 0: 85 super(ordereddict, self).__init__() 86 self.order = [] 87 elif len(args) > 1: 88 raise TypeError("ordereddict() takes at most 1 argument (%d given)" % len(args)) 89 else: 90 initarg = args[0] 91 apply(super(ordereddict, self).__init__, args) 92 if hasattr(initarg, "keys"): 93 self.order = initarg.keys() 94 else: 95 # danger: could have duplicate keys... 96 self.order = [] 97 checkduplicates = {} 98 for key, value in initarg: 99 if not key in checkduplicates: 100 self.order.append(key) 101 checkduplicates[key] = None
102
103 - def __setitem__(self, key, value):
104 alreadypresent = key in self 105 result = dict.__setitem__(self, key, value) 106 if not alreadypresent: self.order.append(key) 107 return result
108
109 - def update(self, updatedict):
110 """D.update(E) -> None. Update D from E: for k in E.keys(): D[k] = E[k]""" 111 for key, value in updatedict.iteritems(): 112 self[key] = value
113
114 - def __delitem__(self, key):
115 alreadypresent = key in self 116 result = dict.__delitem__(self, key) 117 if alreadypresent: del self.order[self.order.index(key)] 118 return result
119
120 - def copy(self):
121 """D.copy() -> a shallow copy of D""" 122 thecopy = ordereddict(super(ordereddict, self).copy()) 123 thecopy.order = self.order[:] 124 return thecopy
125
126 - def items(self):
127 """D.items() -> list of D's (key, value) pairs, as 2-tuples""" 128 return [(key, self[key]) for key in self.order]
129
130 - def iteritems(self):
131 """D.iteritems() -> an iterator over the (key, value) items of D""" 132 for key in self.order: 133 yield (key, self[key])
134
135 - def iterkeys(self):
136 """D.iterkeys() -> an iterator over the keys of D""" 137 for key in self.order: 138 yield key
139 140 __iter__ = iterkeys 141
142 - def itervalues(self):
143 """D.itervalues() -> an iterator over the values of D""" 144 for key in self.order: 145 yield self[key]
146
147 - def keys(self):
148 """D.keys() -> list of D's keys""" 149 return self.order[:]
150
151 - def popitem(self):
152 """D.popitem() -> (k, v), remove and return some (key, value) pair as a 2-tuple; but raise KeyError if D is empty""" 153 if len(self.order) == 0: 154 raise KeyError("popitem(): ordered dictionary is empty") 155 k = self.order.pop() 156 v = self[k] 157 del self[k] 158 return (k,v)
159
160 - def pop(self, key):
161 """remove entry from dict and internal list""" 162 value = super(ordereddict, self).pop(key) 163 del self.order[self.order.index(key)] 164 return value
165