blob: f1fe36f62067cc675e27b8bf8e5e1fc2a8a70cfe (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
from collections import MutableMapping
from itertools import chain
class ChainedDict(MutableMapping):
def __init__(self, parent=None, **kwargs):
self.__parent = parent
self.__deleted_keys = set()
self.__data = kwargs
def __contains__(self, key):
if self.__parent is not None:
return (
(key in self.__data or key in self.__parent)
and key not in self.__deleted_keys
)
return key in self.__data
def __getitem__(self, key):
try:
return self.__data[key]
except KeyError:
if self.__parent is not None and key not in self.__deleted_keys:
return self.__parent[key]
else:
raise
def __setitem__(self, key, val):
self.__data[key] = val
self.__deleted_keys.discard(key)
def __delitem__(self, key):
if key in self:
self.__deleted_keys.add(key)
try:
del self.__data[key]
except KeyError:
pass
else:
raise KeyError(key)
def __repr__(self):
return "{}({})".format(self.__class__.__name__, dict(self.items()))
def __iter__(self):
return self.keys()
def __len__(self):
return len(list(self.keys()))
def iterkeys(self):
yielded = set(self.__deleted_keys)
if self.__parent is None:
iterable = self.__data.keys()
else:
iterable = chain(self.__parent.keys(), self.__data.keys())
for key in iterable:
if key in yielded:
continue
yield key
yielded.add(key)
keys = iterkeys
def iteritems(self):
for key in self.iterkeys():
yield key, self[key]
items = iteritems
|