oops, i changed m5term.doxygen when kev had a lock on it, just use his version
[gem5.git] / python / m5 / multidict.py
1 # Copyright (c) 2005 The Regents of The University of Michigan
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met: redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer;
8 # redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution;
11 # neither the name of the copyright holders nor the names of its
12 # contributors may be used to endorse or promote products derived from
13 # this software without specific prior written permission.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 __all__ = [ 'multidict' ]
28
29 class multidict(object):
30 __nodefault = object()
31 def __init__(self, parent = {}, **kwargs):
32 self.dict = dict(**kwargs)
33 self.parent = parent
34 self.deleted = {}
35
36 def __str__(self):
37 return str(dict(self.items()))
38
39 def __repr__(self):
40 return `dict(self.items())`
41
42 def __contains__(self, key):
43 return self.dict.has_key(key) or self.parent.has_key(key)
44
45 def __delitem__(self, key):
46 try:
47 del self.dict[key]
48 except KeyError, e:
49 if key in self.parent:
50 self.deleted[key] = True
51 else:
52 raise KeyError, e
53
54 def __setitem__(self, key, value):
55 self.deleted.pop(key, False)
56 self.dict[key] = value
57
58 def __getitem__(self, key):
59 try:
60 return self.dict[key]
61 except KeyError, e:
62 if not self.deleted.get(key, False) and key in self.parent:
63 return self.parent[key]
64 else:
65 raise KeyError, e
66
67 def __len__(self):
68 return len(self.dict) + len(self.parent)
69
70 def next(self):
71 for key,value in self.dict.items():
72 yield key,value
73
74 if self.parent:
75 for key,value in self.parent.next():
76 if key not in self.dict and key not in self.deleted:
77 yield key,value
78
79 def has_key(self, key):
80 return key in self
81
82 def iteritems(self):
83 for item in self.next():
84 yield item
85
86 def items(self):
87 return [ item for item in self.next() ]
88
89 def iterkeys(self):
90 for key,value in self.next():
91 yield key
92
93 def keys(self):
94 return [ key for key,value in self.next() ]
95
96 def itervalues(self):
97 for key,value in self.next():
98 yield value
99
100 def values(self):
101 return [ value for key,value in self.next() ]
102
103 def get(self, key, default=__nodefault):
104 try:
105 return self[key]
106 except KeyError, e:
107 if default != self.__nodefault:
108 return default
109 else:
110 raise KeyError, e
111
112 def setdefault(self, key, default):
113 try:
114 return self[key]
115 except KeyError:
116 self.deleted.pop(key, False)
117 self.dict[key] = default
118 return default
119
120 def _dump(self):
121 print 'multidict dump'
122 node = self
123 while isinstance(node, multidict):
124 print ' ', node.dict
125 node = node.parent
126
127 def _dumpkey(self, key):
128 values = []
129 node = self
130 while isinstance(node, multidict):
131 if key in node.dict:
132 values.append(node.dict[key])
133 node = node.parent
134 print key, values
135
136 if __name__ == '__main__':
137 test1 = multidict()
138 test2 = multidict(test1)
139 test3 = multidict(test2)
140 test4 = multidict(test3)
141
142 test1['a'] = 'test1_a'
143 test1['b'] = 'test1_b'
144 test1['c'] = 'test1_c'
145 test1['d'] = 'test1_d'
146 test1['e'] = 'test1_e'
147
148 test2['a'] = 'test2_a'
149 del test2['b']
150 test2['c'] = 'test2_c'
151 del test1['a']
152
153 test2.setdefault('f', multidict)
154
155 print 'test1>', test1.items()
156 print 'test2>', test2.items()
157 #print test1['a']
158 print test1['b']
159 print test1['c']
160 print test1['d']
161 print test1['e']
162
163 print test2['a']
164 #print test2['b']
165 print test2['c']
166 print test2['d']
167 print test2['e']
168
169 for key in test2.iterkeys():
170 print key
171
172 test2.get('g', 'foo')
173 #test2.get('b')
174 test2.get('b', 'bar')
175 test2.setdefault('b', 'blah')
176 print test1
177 print test2
178 print `test2`
179
180 print len(test2)
181
182 test3['a'] = [ 0, 1, 2, 3 ]
183
184 print test4