1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 -class ImmutableDict(tuple):
20
22 if (len(args) == 1 and
23 len(kwargs) == 0 and
24 isinstance(args[0], _AlreadyCopiedDict)):
25 d = args[0].value
26 else:
27 d = {}
28 for arg in args:
29 d.update(arg)
30 for key, value in kwargs.items():
31 d[key] = value
32 return tuple.__new__(cls, (d,))
33
34 @property
37
38 - def update(self, *args, **kwargs):
39 return self.__class__(self._internal, *args, **kwargs)
40
42 new = {}
43 new.update(self._internal)
44 del new[key]
45 return self.__class__(_AlreadyCopiedDict(new))
46
48 return self.__class__(_AlreadyCopiedDict({
49 key: fn(value)
50 for key, value
51 in self._internal.items()
52 }))
53
54 - def get(self, name, default=None):
56
58 return len(self._internal)
59
61 return item in self._internal
62
64 return self._internal[name]
65
67 return iter(self._internal.items())
68
70 return (
71 isinstance(other, self.__class__) and
72 self._internal == other._internal
73 )
74
76 return not self == other
77
79 items = []
80 items.append(self.__class__.__name__)
81 items.append("({\n")
82 for key, value in self:
83 items.append(" ")
84 items.append(repr(key))
85 items.append(": ")
86 for index, line in enumerate(repr(value).split("\n")):
87 if index > 0:
88 items.append("\n ")
89 items.append(line)
90 items.append(",\n")
91 items.append("})")
92 return "".join(items)
93
116
122
125
126 - def __new__(cls, *args, **kwargs):
127 defaults = {
128 key: value.default
129 for key, value
130 in cls._immutable_record_fields.items()
131 }
132 d = ImmutableDict.__new__(cls, defaults, *args, **kwargs)
133 for key, value in d:
134 if key not in cls._immutable_record_fields:
135 raise ValueError("{0!r} is not a valid field of {1}".format(
136 key,
137 cls.__name__
138 ))
139 return d
140
143
144 """
145 A special value that can be passed as the single value to the constructor
146 of ImmutableDict to prevent unnecessary copying.
147 """
148
151