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

60 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-07 08:32 -0700

1from collections.abc import Iterator 

2from typing import override 

3 

4from ..blob import BytesBlob 

5from . import BlobDictBase 

6 

7 

8class MultiReplicaBlobDict(BlobDictBase): 

9 def __init__( 

10 self, 

11 replica_dicts: dict[str, BlobDictBase], 

12 ) -> None: 

13 super().__init__() 

14 

15 self.__replica_dicts: dict[str, BlobDictBase] = replica_dicts 

16 self.__primary_dict: BlobDictBase = next(iter(replica_dicts.values())) 

17 

18 @override 

19 def __len__(self) -> int: 

20 return len(self.__primary_dict) 

21 

22 def len( 

23 self, 

24 *, 

25 replica_name: str | None = None, 

26 ) -> int: 

27 return len( 

28 self.__replica_dicts[replica_name] if replica_name 

29 else self.__primary_dict, 

30 ) 

31 

32 @override 

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

34 return self.contains(key) 

35 

36 def contains( 

37 self, 

38 key: str, 

39 *, 

40 replica_names: set[str] | None = None, 

41 ) -> bool: 

42 return any( 

43 key in self.__replica_dicts[replica_name] 

44 for replica_name in ( 

45 self.__replica_dicts.keys() if replica_names is None 

46 else replica_names 

47 ) 

48 ) 

49 

50 @override 

51 def get( 

52 self, 

53 key: str, 

54 default: BytesBlob | None = None, 

55 *, 

56 replica_names: set[str] | None = None, 

57 ) -> BytesBlob | None: 

58 for replica_name in ( 

59 self.__replica_dicts.keys() if replica_names is None 

60 else replica_names 

61 ): 

62 replica_dict: BlobDictBase = self.__replica_dicts[replica_name] 

63 blob: BytesBlob | None 

64 if blob := replica_dict.get(key, default): 

65 return blob 

66 

67 return default 

68 

69 @override 

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

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

72 if blob is None: 

73 raise KeyError 

74 

75 return blob 

76 

77 @override 

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

79 yield from ( 

80 key for key in self.__primary_dict 

81 ) 

82 

83 def iter( 

84 self, 

85 *, 

86 replica_name: str | None = None, 

87 ) -> Iterator[str]: 

88 yield from ( 

89 key for key in ( 

90 self.__replica_dicts[replica_name] if replica_name 

91 else self.__primary_dict 

92 ) 

93 ) 

94 

95 @override 

96 def clear( 

97 self, 

98 *, 

99 replica_names: set[str] | None = None, 

100 ) -> None: 

101 for replica_name in ( 

102 self.__replica_dicts.keys() if replica_names is None 

103 else replica_names 

104 ): 

105 replica_dict: BlobDictBase = self.__replica_dicts[replica_name] 

106 replica_dict.clear() 

107 

108 @override 

109 def pop( 

110 self, 

111 key: str, 

112 default: BytesBlob | None = None, 

113 *, 

114 replica_names: set[str] | None = None, 

115 ) -> BytesBlob | None: 

116 final_blob: BytesBlob | None = default 

117 for replica_name in ( 

118 self.__replica_dicts.keys() if replica_names is None 

119 else replica_names 

120 ): 

121 replica_dict: BlobDictBase = self.__replica_dicts[replica_name] 

122 if (blob := replica_dict.pop(key)) and not final_blob: 

123 final_blob = blob 

124 

125 return final_blob 

126 

127 @override 

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

129 if key not in self: 

130 raise KeyError 

131 

132 self.pop(key) 

133 

134 @override 

135 def __setitem__( 

136 self, 

137 key: str, 

138 blob: BytesBlob, 

139 *, 

140 replica_names: set[str] | None = None, 

141 ) -> None: 

142 for replica_name in ( 

143 self.__replica_dicts.keys() if replica_names is None 

144 else replica_names 

145 ): 

146 replica_dict: BlobDictBase = self.__replica_dicts[replica_name] 

147 replica_dict[key] = blob