Commit | Line | Data |
---|---|---|
c638d827 CR |
1 | class MultiMapping: |
2 | def __init__(self, *stores): | |
3 | self.stores = list(stores) | |
4 | self.stores.reverse() | |
5 | ||
6 | def __getitem__(self, key): | |
7 | for store in self.stores: | |
8 | if store.has_key(key): | |
9 | return store[key] | |
10 | raise KeyError, key | |
11 | ||
12 | def __setitem__(self, key, val): | |
13 | self.stores[0][key] = val | |
14 | ||
15 | _marker = [] | |
16 | ||
17 | def get(self, key, default=_marker): | |
18 | for store in self.stores: | |
19 | if store.has_key(key): | |
20 | return store[key] | |
21 | if default is self._marker: | |
22 | raise KeyError, key | |
23 | return default | |
24 | ||
25 | def __len__(self): | |
26 | return len(self.items()) | |
27 | ||
28 | def has_key(self, key): | |
29 | for store in self.stores: | |
30 | if store.has_key(key): | |
31 | return 1 | |
32 | return 0 | |
33 | ||
34 | def push(self, store): | |
35 | self.stores = [store] + self.stores | |
36 | ||
37 | def pop(self): | |
38 | if not len(self.stores): | |
39 | return None | |
40 | store, self.stores = self.stores[0], self.stores[1:] | |
41 | return store | |
42 | ||
43 | def keys(self): | |
44 | return [ _[0] for _ in self.items() ] | |
45 | ||
46 | def values(self): | |
47 | return [ _[1] for _ in self.items() ] | |
48 | ||
49 | def copy(self): | |
50 | copy = MultiMapping() | |
51 | copy.stores = [_.copy() for _ in self.stores] | |
52 | return copy | |
53 | ||
54 | def items(self): | |
55 | l = [] | |
56 | seen = {} | |
57 | for store in self.stores: | |
58 | for k, v in store.items(): | |
59 | if not seen.has_key(k): | |
60 | l.append((k, v)) | |
61 | seen[k] = 1 | |
62 | return l | |
63 |