Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/werkzeug/datastructures/mixins.py: 50%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

139 statements  

1from __future__ import annotations 

2 

3from itertools import repeat 

4 

5from .._internal import _missing 

6 

7 

8def is_immutable(self): 

9 raise TypeError(f"{type(self).__name__!r} objects are immutable") 

10 

11 

12class ImmutableListMixin: 

13 """Makes a :class:`list` immutable. 

14 

15 .. versionadded:: 0.5 

16 

17 :private: 

18 """ 

19 

20 _hash_cache = None 

21 

22 def __hash__(self): 

23 if self._hash_cache is not None: 

24 return self._hash_cache 

25 rv = self._hash_cache = hash(tuple(self)) 

26 return rv 

27 

28 def __reduce_ex__(self, protocol): 

29 return type(self), (list(self),) 

30 

31 def __delitem__(self, key): 

32 is_immutable(self) 

33 

34 def __iadd__(self, other): 

35 is_immutable(self) 

36 

37 def __imul__(self, other): 

38 is_immutable(self) 

39 

40 def __setitem__(self, key, value): 

41 is_immutable(self) 

42 

43 def append(self, item): 

44 is_immutable(self) 

45 

46 def remove(self, item): 

47 is_immutable(self) 

48 

49 def extend(self, iterable): 

50 is_immutable(self) 

51 

52 def insert(self, pos, value): 

53 is_immutable(self) 

54 

55 def pop(self, index=-1): 

56 is_immutable(self) 

57 

58 def reverse(self): 

59 is_immutable(self) 

60 

61 def sort(self, key=None, reverse=False): 

62 is_immutable(self) 

63 

64 

65class ImmutableDictMixin: 

66 """Makes a :class:`dict` immutable. 

67 

68 .. versionadded:: 0.5 

69 

70 :private: 

71 """ 

72 

73 _hash_cache = None 

74 

75 @classmethod 

76 def fromkeys(cls, keys, value=None): 

77 instance = super().__new__(cls) 

78 instance.__init__(zip(keys, repeat(value))) 

79 return instance 

80 

81 def __reduce_ex__(self, protocol): 

82 return type(self), (dict(self),) 

83 

84 def _iter_hashitems(self): 

85 return self.items() 

86 

87 def __hash__(self): 

88 if self._hash_cache is not None: 

89 return self._hash_cache 

90 rv = self._hash_cache = hash(frozenset(self._iter_hashitems())) 

91 return rv 

92 

93 def setdefault(self, key, default=None): 

94 is_immutable(self) 

95 

96 def update(self, *args, **kwargs): 

97 is_immutable(self) 

98 

99 def pop(self, key, default=None): 

100 is_immutable(self) 

101 

102 def popitem(self): 

103 is_immutable(self) 

104 

105 def __setitem__(self, key, value): 

106 is_immutable(self) 

107 

108 def __delitem__(self, key): 

109 is_immutable(self) 

110 

111 def clear(self): 

112 is_immutable(self) 

113 

114 

115class ImmutableMultiDictMixin(ImmutableDictMixin): 

116 """Makes a :class:`MultiDict` immutable. 

117 

118 .. versionadded:: 0.5 

119 

120 :private: 

121 """ 

122 

123 def __reduce_ex__(self, protocol): 

124 return type(self), (list(self.items(multi=True)),) 

125 

126 def _iter_hashitems(self): 

127 return self.items(multi=True) 

128 

129 def add(self, key, value): 

130 is_immutable(self) 

131 

132 def popitemlist(self): 

133 is_immutable(self) 

134 

135 def poplist(self, key): 

136 is_immutable(self) 

137 

138 def setlist(self, key, new_list): 

139 is_immutable(self) 

140 

141 def setlistdefault(self, key, default_list=None): 

142 is_immutable(self) 

143 

144 

145class ImmutableHeadersMixin: 

146 """Makes a :class:`Headers` immutable. We do not mark them as 

147 hashable though since the only usecase for this datastructure 

148 in Werkzeug is a view on a mutable structure. 

149 

150 .. versionadded:: 0.5 

151 

152 :private: 

153 """ 

154 

155 def __delitem__(self, key, **kwargs): 

156 is_immutable(self) 

157 

158 def __setitem__(self, key, value): 

159 is_immutable(self) 

160 

161 def set(self, _key, _value, **kwargs): 

162 is_immutable(self) 

163 

164 def setlist(self, key, values): 

165 is_immutable(self) 

166 

167 def add(self, _key, _value, **kwargs): 

168 is_immutable(self) 

169 

170 def add_header(self, _key, _value, **_kwargs): 

171 is_immutable(self) 

172 

173 def remove(self, key): 

174 is_immutable(self) 

175 

176 def extend(self, *args, **kwargs): 

177 is_immutable(self) 

178 

179 def update(self, *args, **kwargs): 

180 is_immutable(self) 

181 

182 def insert(self, pos, value): 

183 is_immutable(self) 

184 

185 def pop(self, key=None, default=_missing): 

186 is_immutable(self) 

187 

188 def popitem(self): 

189 is_immutable(self) 

190 

191 def setdefault(self, key, default): 

192 is_immutable(self) 

193 

194 def setlistdefault(self, key, default): 

195 is_immutable(self) 

196 

197 

198def _calls_update(name): 

199 def oncall(self, *args, **kw): 

200 rv = getattr(super(UpdateDictMixin, self), name)(*args, **kw) 

201 

202 if self.on_update is not None: 

203 self.on_update(self) 

204 

205 return rv 

206 

207 oncall.__name__ = name 

208 return oncall 

209 

210 

211class UpdateDictMixin(dict): 

212 """Makes dicts call `self.on_update` on modifications. 

213 

214 .. versionadded:: 0.5 

215 

216 :private: 

217 """ 

218 

219 on_update = None 

220 

221 def setdefault(self, key, default=None): 

222 modified = key not in self 

223 rv = super().setdefault(key, default) 

224 if modified and self.on_update is not None: 

225 self.on_update(self) 

226 return rv 

227 

228 def pop(self, key, default=_missing): 

229 modified = key in self 

230 if default is _missing: 

231 rv = super().pop(key) 

232 else: 

233 rv = super().pop(key, default) 

234 if modified and self.on_update is not None: 

235 self.on_update(self) 

236 return rv 

237 

238 __setitem__ = _calls_update("__setitem__") 

239 __delitem__ = _calls_update("__delitem__") 

240 clear = _calls_update("clear") 

241 popitem = _calls_update("popitem") 

242 update = _calls_update("update")