Coverage for tests/test_dict.py: 8%

190 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-09-11 01:02 -0700

1# This file is part of daf_base 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org/). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22"""Test dict emulation""" 

23 

24import unittest 

25import copy 

26 

27import lsst.daf.base 

28 

29 

30class DictTestCase(unittest.TestCase): 

31 

32 def setUp(self): 

33 

34 pl = lsst.daf.base.PropertyList() 

35 pl.setBool("bool", True) 

36 pl.setShort("short", 42) 

37 pl.setInt("int", 2008) 

38 pl.setLongLong("int64_t", 0xfeeddeadbeef) 

39 pl.setFloat("float", 3.14159) 

40 pl.setDouble("double", 2.718281828459045) 

41 pl.set("char*", "foo", "char comment") 

42 pl.setString("string", "bar") 

43 pl.set("int2", 2009, "int comment") 

44 pl.set("dt", lsst.daf.base.DateTime("20090402T072639.314159265Z", lsst.daf.base.DateTime.UTC)) 

45 pl.set("undef", None) 

46 

47 ps = lsst.daf.base.PropertySet() 

48 ps.setBool("bool", True) 

49 ps.setShort("short", 42) 

50 ps.setInt("int", 2008) 

51 ps.setLongLong("long", 5) # Deliberately small 

52 ps.setLongLong("int64_t", 0xfeeddeadbeef) 

53 ps.setFloat("float", 3.14159) 

54 ps.setDouble("double", 2.718281828459045) 

55 ps.set("char*", "foo") 

56 ps.setString("string", "bar") 

57 ps.set("char*", u"foo") 

58 ps.setString("string", u"bar") 

59 ps.set("int2", 2009) 

60 ps.set("dt", lsst.daf.base.DateTime("20090402T072639.314159265Z", lsst.daf.base.DateTime.UTC)) 

61 ps.set("blank", "") 

62 ps.addInt("int", 2009) 

63 ps.set("undef", None) 

64 

65 ps2 = lsst.daf.base.PropertySet() 

66 ps2.setBool("bool2", False) 

67 ps2.setShort("short2", 16) 

68 ps2.setInt("int2", 2018) 

69 

70 ps.setPropertySet("ps2", ps2) 

71 pl.setPropertySet("ps2", ps2) 

72 

73 self.ps = ps 

74 self.pl = pl 

75 

76 def testShallowCopyPropertySet(self): 

77 shallow = copy.copy(self.ps) 

78 self.assertIsInstance(shallow, lsst.daf.base.PropertySet) 

79 self.assertIn("ps2", shallow) 

80 self.assertEqual(shallow, self.ps) 

81 

82 # Modifying the attached property set should change both views 

83 ps2 = self.ps.getScalar("ps2") 

84 ps2s = shallow.getScalar("ps2") 

85 self.assertEqual(ps2, ps2s) 

86 

87 ps2["int2"] = 2017 

88 self.assertEqual(ps2, ps2s) 

89 

90 def testDeepCopyPropertySet(self): 

91 deep = copy.deepcopy(self.ps) 

92 self.assertIsInstance(deep, lsst.daf.base.PropertySet) 

93 self.assertEqual(deep, self.ps) 

94 

95 # Modifying the contents of ps2 should not affect the original 

96 ps2 = self.ps.getScalar("ps2") 

97 ps2d = deep.getScalar("ps2") 

98 self.assertEqual(ps2, ps2d) 

99 

100 ps2["int2"] = 2017 

101 self.assertNotEqual(ps2, ps2d) 

102 

103 def testDictPropertySet(self): 

104 container = self.ps 

105 self.assertIn("string", container) 

106 self.assertIn("ps2", container) 

107 self.assertNotIn("ps2.bool2", container) 

108 self.assertIn("bool2", container.getScalar("ps2")) 

109 

110 # Compare dict-like interface to pure dict version 

111 d = container.toDict() 

112 self.assertEqual(len(d), len(container)) 

113 self.assertIsNone(d["undef"]) 

114 

115 # Set some values 

116 container["new"] = "string" 

117 container["array"] = [1, 2, 3] 

118 container["dot.delimited"] = "delimited" 

119 self.assertIn("dot", container) 

120 

121 keys = container.keys() 

122 self.assertEqual(len(keys), 17) 

123 for k in keys: 

124 self.assertIn(k, container) 

125 

126 for k, v in container.items(): 

127 self.assertIn(k, container) 

128 self.assertEqual(v, container[k]) 

129 

130 # Check that string form of the non-PropertySet values are present 

131 # when iterating over values. This is a simple test to ensure 

132 # that values() does do something useful 

133 values = {str(container[k]) for k in container if not isinstance(container[k], 

134 lsst.daf.base.PropertySet)} 

135 for v in container.values(): 

136 if not isinstance(v, lsst.daf.base.PropertySet): 

137 self.assertIn(str(v), values) 

138 

139 # Assign a PropertySet 

140 ps2 = lsst.daf.base.PropertySet() 

141 ps2.setString("newstring", "stringValue") 

142 container["newps2"] = ps2 

143 ps2["newint"] = 5 

144 self.assertEqual(container.getScalar("newps2.newint"), ps2.getScalar("newint")) 

145 

146 ps2["undef2"] = None 

147 self.assertIn("undef2", ps2) 

148 

149 # Dict should be converted to a PropertySet 

150 container["dict"] = {"a": 1, "b": 2} 

151 self.assertEqual(container.getScalar("dict.b"), 2) 

152 

153 container["a_property_list"] = self.pl 

154 

155 # Upgrading of integer 

156 key = "upgrade" 

157 container[key] = 1 

158 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int) 

159 self.assertEqual(container[key], 1) 

160 

161 # Set to 64-bit int value 

162 container[key] = 8589934592 

163 self.assertEqual(container[key], 8589934592) 

164 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

165 

166 # Set to small int again, type should not change 

167 container[key] = 42 

168 self.assertEqual(container[key], 42) 

169 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

170 

171 def testPop(self): 

172 container = self.ps 

173 self.assertEqual(container.pop("int"), 2009) 

174 self.assertNotIn("int", container) 

175 self.assertEqual(container.pop("not_there", 42), 42) 

176 with self.assertRaises(KeyError): 

177 container.pop("not_there") 

178 

179 def testDictPropertyList(self): 

180 container = self.pl 

181 self.assertIn("string", container) 

182 self.assertIn("ps2.bool2", container) 

183 

184 # Set a comment 

185 container["int2#COMMENT"] = "new comment" 

186 self.assertEqual(container.getComment("int2"), "new comment") 

187 

188 # Compare dict-like interface to pure dict version 

189 d = container.toDict() 

190 self.assertEqual(len(d), len(container)) 

191 self.assertIsNone(d["undef"]) 

192 

193 # Set some values 

194 container["new"] = "string" 

195 container["array"] = [1, 2, 3] 

196 container["dot.delimited"] = "delimited" 

197 

198 keys = container.keys() 

199 self.assertEqual(len(keys), 17) 

200 for k in keys: 

201 self.assertIn(k, container) 

202 

203 for k, v in container.items(): 

204 self.assertIn(k, container) 

205 self.assertEqual(v, container[k]) 

206 

207 # Assign a PropertySet 

208 ps2 = lsst.daf.base.PropertySet() 

209 ps2["newstring"] = "stringValue" 

210 container["newps2"] = ps2 

211 ps2["newint"] = 5 # This should have no effect on container 

212 self.assertEqual(container.getScalar("newps2.newstring"), ps2.getScalar("newstring")) 

213 self.assertNotIn("newps2.newinst", container) 

214 self.assertIn("newint", ps2) 

215 

216 ps2["undef2"] = None 

217 self.assertIn("undef2", ps2) 

218 

219 # Dict should be converted to a PropertySet 

220 container["dict"] = {"a": 1, "b": 2} 

221 self.assertEqual(container.getScalar("dict.b"), 2) 

222 

223 # Upgrading of integer 

224 key = "upgrade" 

225 container[key] = 1 

226 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int) 

227 self.assertEqual(container[key], 1) 

228 container[key] = 8589934592 

229 self.assertEqual(container[key], 8589934592) 

230 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

231 

232 # Set to small int again, type should not change 

233 container[key] = 42 

234 self.assertEqual(container[key], 42) 

235 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

236 

237 # Check that 0 ends up with the correct type 

238 key = "zero" 

239 container[key] = 0 

240 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int) 

241 

242 # And again but bouncing through an Undef 

243 key = "zeroundef" 

244 container[key] = None 

245 container[key] = 0 

246 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_Int) 

247 

248 # Store an array of integers with a large value 

249 key = "intarray" 

250 testArray = [1, 8589934592, 3] 

251 container[key] = testArray 

252 self.assertEqual(container.getArray(key), testArray) 

253 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

254 

255 container[key] = [-1, 2, 3] 

256 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_LongLong) 

257 

258 container[key] = [1, 2, 2**63 + 1] 

259 self.assertEqual(container.typeOf(key), lsst.daf.base.PropertySet.TYPE_UnsignedLongLong) 

260 

261 # Store an empty list 

262 container["emptylist"] = [] 

263 self.assertNotIn("emptylist", container) 

264 

265 with self.assertRaises(TypeError): 

266 # This can't fit LongLong but also contains negative number 

267 container[key] = [-1, 2, 2**63 + 1] 

268 

269 def testCopyPropertyList(self): 

270 # For PropertyList shallow copy and deep copy are identical 

271 shallow = copy.copy(self.pl) 

272 self.assertIsInstance(shallow, lsst.daf.base.PropertyList) 

273 self.assertIn("dt", shallow) 

274 self.assertIn("int", shallow) 

275 self.assertEqual(shallow, self.pl) 

276 del shallow["dt"] 

277 self.assertNotIn("dt", shallow) 

278 self.assertIn("dt", self.pl) 

279 

280 deep = copy.deepcopy(self.pl) 

281 self.assertIsInstance(deep, lsst.daf.base.PropertyList) 

282 self.assertEqual(deep, self.pl) 

283 del deep["dt"] 

284 self.assertNotIn("dt", deep) 

285 self.assertIn("dt", self.pl) 

286 

287 

288if __name__ == '__main__': 288 ↛ 289line 288 didn't jump to line 289, because the condition on line 288 was never true

289 unittest.main()