Coverage for src/blob_dict/dict/primary_secondary.py: 0%

78 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-03-19 19:57 -0700

1from collections.abc import Iterator 

2from typing import override 

3 

4from ..blob import BytesBlob 

5from . import BlobDictBase 

6 

7 

8class PrimarySecondaryBlobDict(BlobDictBase): 

9 def __init__( 

10 self, 

11 primary_dict: BlobDictBase, 

12 secondary_dicts: dict[str, BlobDictBase], 

13 ) -> None: 

14 super().__init__() 

15 

16 self.__primary_dict: BlobDictBase = primary_dict 

17 self.__secondary_dicts: dict[str, BlobDictBase] = secondary_dicts 

18 

19 @override 

20 def create( 

21 self, 

22 *, 

23 secondary_dict_names: set[str] | None = None, 

24 ) -> None: 

25 self.__primary_dict.create() 

26 

27 for secondary_dict_name in ( 

28 self.__secondary_dicts.keys() if secondary_dict_names is None 

29 else secondary_dict_names 

30 ): 

31 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

32 secondary_dict.create() 

33 

34 @override 

35 def delete( 

36 self, 

37 *, 

38 secondary_dict_names: set[str] | None = None, 

39 ) -> None: 

40 self.__primary_dict.delete() 

41 

42 for secondary_dict_name in ( 

43 self.__secondary_dicts.keys() if secondary_dict_names is None 

44 else secondary_dict_names 

45 ): 

46 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

47 secondary_dict.delete() 

48 

49 @override 

50 def __len__(self) -> int: 

51 return len(self.__primary_dict) 

52 

53 def len( 

54 self, 

55 *, 

56 secondary_dict_name: str | None = None, 

57 ) -> int: 

58 return len( 

59 self.__secondary_dicts[secondary_dict_name] if secondary_dict_name 

60 else self.__primary_dict, 

61 ) 

62 

63 @override 

64 def __contains__(self, key: str) -> bool: 

65 return self.contains(key) 

66 

67 def contains( 

68 self, 

69 key: str, 

70 *, 

71 secondary_dict_names: set[str] | None = None, 

72 ) -> bool: 

73 return ( 

74 key in self.__primary_dict 

75 or any( 

76 key in self.__secondary_dicts[secondary_dict_name] 

77 for secondary_dict_name in ( 

78 self.__secondary_dicts.keys() if secondary_dict_names is None 

79 else secondary_dict_names 

80 ) 

81 ) 

82 ) 

83 

84 @override 

85 def get( 

86 self, 

87 key: str, 

88 default: BytesBlob | None = None, 

89 *, 

90 secondary_dict_names: set[str] | None = None, 

91 ) -> BytesBlob | None: 

92 blob: BytesBlob | None 

93 if blob := self.__primary_dict.get(key): 

94 return blob 

95 

96 for secondary_dict_name in ( 

97 self.__secondary_dicts.keys() if secondary_dict_names is None 

98 else secondary_dict_names 

99 ): 

100 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

101 if blob := secondary_dict.get(key, default): 

102 return blob 

103 

104 return default 

105 

106 @override 

107 def __getitem__(self, key: str) -> BytesBlob: 

108 blob: BytesBlob | None = self.get(key) 

109 if blob is None: 

110 raise KeyError 

111 

112 return blob 

113 

114 @override 

115 def __iter__(self) -> Iterator[str]: 

116 yield from ( 

117 key for key in self.__primary_dict 

118 ) 

119 

120 def iter( 

121 self, 

122 *, 

123 secondary_dict_name: str | None = None, 

124 ) -> Iterator[str]: 

125 yield from ( 

126 key for key in ( 

127 self.__secondary_dicts[secondary_dict_name] if secondary_dict_name 

128 else self.__primary_dict 

129 ) 

130 ) 

131 

132 @override 

133 def clear( 

134 self, 

135 *, 

136 secondary_dict_names: set[str] | None = None, 

137 ) -> None: 

138 self.__primary_dict.clear() 

139 

140 for secondary_dict_name in ( 

141 self.__secondary_dicts.keys() if secondary_dict_names is None 

142 else secondary_dict_names 

143 ): 

144 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

145 secondary_dict.clear() 

146 

147 @override 

148 def pop( 

149 self, 

150 key: str, 

151 default: BytesBlob | None = None, 

152 *, 

153 secondary_dict_names: set[str] | None = None, 

154 ) -> BytesBlob | None: 

155 final_blob: BytesBlob | None = default 

156 

157 if blob := self.__primary_dict.pop(key): 

158 final_blob = blob 

159 

160 for secondary_dict_name in ( 

161 self.__secondary_dicts.keys() if secondary_dict_names is None 

162 else secondary_dict_names 

163 ): 

164 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

165 if (blob := secondary_dict.pop(key)) and not final_blob: 

166 final_blob = blob 

167 

168 return final_blob 

169 

170 @override 

171 def __delitem__(self, key: str) -> None: 

172 if key not in self: 

173 raise KeyError 

174 

175 self.pop(key) 

176 

177 @override 

178 def __setitem__( 

179 self, 

180 key: str, 

181 blob: BytesBlob, 

182 *, 

183 secondary_dict_names: set[str] | None = None, 

184 ) -> None: 

185 self.__primary_dict[key] = blob 

186 

187 for secondary_dict_name in ( 

188 self.__secondary_dicts.keys() if secondary_dict_names is None 

189 else secondary_dict_names 

190 ): 

191 secondary_dict: BlobDictBase = self.__secondary_dicts[secondary_dict_name] 

192 secondary_dict[key] = blob