smartdict.py revision 1530
1# The SmartDict class fixes a couple of issues with using the content 2# of os.environ or similar dicts of strings as Python variables: 3# 4# 1) Undefined variables should return False rather than raising KeyError. 5# 6# 2) String values of 'False', '0', etc., should evaluate to False 7# (not just the empty string). 8# 9# #1 is solved by overriding __getitem__, and #2 is solved by using a 10# proxy class for values and overriding __nonzero__ on the proxy. 11# Everything else is just to (a) make proxies behave like normal 12# values otherwise, (b) make sure any dict operation returns a proxy 13# rather than a normal value, and (c) coerce values written to the 14# dict to be strings. 15 16 17from convert import * 18 19class SmartDict(dict): 20 21 class Proxy(str): 22 def __int__(self): 23 return int(to_integer(str(self))) 24 def __long__(self): 25 return long(to_integer(str(self))) 26 def __float__(self): 27 return float(to_integer(str(self))) 28 def __nonzero__(self): 29 return to_bool(str(self)) 30 def convert(self, other): 31 t = type(other) 32 if t == bool: 33 return bool(self) 34 if t == int: 35 return int(self) 36 if t == long: 37 return long(self) 38 if t == float: 39 return float(self) 40 return str(self) 41 def __lt__(self, other): 42 return self.convert(other) < other 43 def __le__(self, other): 44 return self.convert(other) <= other 45 def __eq__(self, other): 46 return self.convert(other) == other 47 def __ne__(self, other): 48 return self.convert(other) != other 49 def __gt__(self, other): 50 return self.convert(other) > other 51 def __ge__(self, other): 52 return self.convert(other) >= other 53 54 def __add__(self, other): 55 return self.convert(other) + other 56 def __sub__(self, other): 57 return self.convert(other) - other 58 def __mul__(self, other): 59 return self.convert(other) * other 60 def __div__(self, other): 61 return self.convert(other) / other 62 def __truediv__(self, other): 63 return self.convert(other) / other 64 65 def __radd__(self, other): 66 return other + self.convert(other) 67 def __rsub__(self, other): 68 return other - self.convert(other) 69 def __rmul__(self, other): 70 return other * self.convert(other) 71 def __rdiv__(self, other): 72 return other / self.convert(other) 73 def __rtruediv__(self, other): 74 return other / self.convert(other) 75 76 77 def __getitem__(self, key): 78 return self.Proxy(dict.get(self, key, 'False')) 79 80 def __setitem__(self, key, item): 81 dict.__setitem__(self, key, str(item)) 82 83 def values(self): 84 return [ self.Proxy(v) for v in dict.values(self) ] 85 86 def itervalues(self): 87 for value in dict.itervalues(self): 88 yield self.Proxy(value) 89 90 def items(self): 91 return [ (k, self.Proxy(v)) for k,v in dict.items(self) ] 92 93 def iteritems(self): 94 for key,value in dict.iteritems(self): 95 yield key, self.Proxy(value) 96 97 def get(self, key, default='False'): 98 return self.Proxy(dict.get(self, key, str(default))) 99 100 def setdefault(self, key, default='False'): 101 return self.Proxy(dict.setdefault(self, key, str(default))) 102 103