Coverage for tests/test_wrappers.py: 14%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

350 statements  

1# This file is part of utils. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

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

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

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12import numpy as np 

13import unittest 

14import lsst.utils.tests 

15import lsst.utils 

16 

17 

18class MockClass: # continued class needs to be at module scope 

19 

20 def method1(self): 

21 return self 

22 

23 @classmethod 

24 def method2(cls): 

25 return cls 

26 

27 @staticmethod 

28 def method3(): 

29 return True 

30 

31 @property 

32 def property1(self): 

33 return False 

34 

35 

36class DecoratorsTestCase(lsst.utils.tests.TestCase): 

37 

38 def setUp(self): 

39 @lsst.utils.continueClass 

40 class MockClass: 

41 

42 def method1a(self): 

43 return self 

44 

45 @classmethod 

46 def method2a(cls): 

47 return cls 

48 

49 @staticmethod 

50 def method3a(): 

51 return True 

52 

53 @property 

54 def property1a(self): 

55 return False 

56 

57 @lsst.utils.inClass(MockClass) 

58 def method1b(self): 

59 return self 

60 

61 @lsst.utils.inClass(MockClass) 

62 @classmethod 

63 def method2b(cls): 

64 return cls 

65 

66 @lsst.utils.inClass(MockClass) 

67 @staticmethod 

68 def method3b(): 

69 return True 

70 

71 @lsst.utils.inClass(MockClass) 

72 @property 

73 def property1b(self): 

74 return False 

75 

76 def testAttributeCopying(self): 

77 x = MockClass() 

78 self.assertIs(x.method1(), x) 

79 self.assertIs(x.method1a(), x) 

80 self.assertIs(x.method1b(), x) 

81 self.assertIs(x.method2(), MockClass) 

82 self.assertIs(x.method2a(), MockClass) 

83 self.assertIs(x.method2b(), MockClass) 

84 self.assertIs(MockClass.method2(), MockClass) 

85 self.assertIs(MockClass.method2a(), MockClass) 

86 self.assertIs(MockClass.method2b(), MockClass) 

87 self.assertTrue(x.method3()) 

88 self.assertTrue(x.method3a()) 

89 self.assertTrue(x.method3b()) 

90 self.assertTrue(MockClass.method3()) 

91 self.assertTrue(MockClass.method3a()) 

92 self.assertTrue(MockClass.method3b()) 

93 self.assertFalse(x.property1) 

94 self.assertFalse(x.property1a) 

95 self.assertFalse(x.property1b) 

96 

97 

98class TemplateMetaSimpleTestCase(lsst.utils.tests.TestCase): 

99 """Test TemplateMeta on a mockup of a template with a single dtype 

100 template parameter. 

101 """ 

102 

103 def setUp(self): 

104 

105 class Example(metaclass=lsst.utils.TemplateMeta): 

106 

107 def method1(self): 

108 return self 

109 

110 @classmethod 

111 def method2(cls): 

112 return cls 

113 

114 @staticmethod 

115 def method3(): 

116 return True 

117 

118 @property 

119 def property1(self): 

120 return False 

121 

122 class ExampleF: 

123 pass 

124 

125 class ExampleD: 

126 pass 

127 

128 self.Example = Example 

129 self.ExampleF = ExampleF 

130 self.ExampleD = ExampleD 

131 

132 def register(self): 

133 self.Example.register(np.float32, self.ExampleF) 

134 self.Example.register(np.float64, self.ExampleD) 

135 

136 def alias(self): 

137 self.Example.alias("F", self.ExampleF) 

138 self.Example.alias("D", self.ExampleD) 

139 

140 def testCorrectRegistration(self): 

141 self.register() 

142 self.assertEqual(self.ExampleF.dtype, np.float32) 

143 self.assertEqual(self.ExampleD.dtype, np.float64) 

144 self.assertIn(np.float32, self.Example) 

145 self.assertIn(np.float64, self.Example) 

146 self.assertEqual(self.Example[np.float32], self.ExampleF) 

147 self.assertEqual(self.Example[np.float64], self.ExampleD) 

148 

149 def testAliases(self): 

150 self.register() 

151 self.alias() 

152 self.assertEqual(self.ExampleF.dtype, np.float32) 

153 self.assertEqual(self.ExampleD.dtype, np.float64) 

154 self.assertIn("F", self.Example) 

155 self.assertIn("D", self.Example) 

156 self.assertEqual(self.Example["F"], self.ExampleF) 

157 self.assertEqual(self.Example["D"], self.ExampleD) 

158 self.assertEqual(self.Example["F"], self.Example[np.float32]) 

159 self.assertEqual(self.Example["D"], self.Example[np.float64]) 

160 

161 def testInheritanceHooks(self): 

162 self.register() 

163 self.assertTrue(issubclass(self.ExampleF, self.Example)) 

164 self.assertTrue(issubclass(self.ExampleD, self.Example)) 

165 f = self.ExampleF() 

166 d = self.ExampleD() 

167 self.assertIsInstance(f, self.Example) 

168 self.assertIsInstance(d, self.Example) 

169 self.assertEqual(set(self.Example.__subclasses__()), set([self.ExampleF, self.ExampleD])) 

170 

171 # To test fallback code path, ensure that there are multiple 

172 # examples to check. 

173 class ExampleSub(self.ExampleD): 

174 # A subclass that is not itself registered. 

175 pass 

176 

177 class Example2(metaclass=lsst.utils.TemplateMeta): 

178 # A new independent class. 

179 pass 

180 

181 class Example2I: 

182 # Something that will be registered in independent hierarchy. 

183 pass 

184 

185 Example2.register(np.int32, Example2I) 

186 

187 sub = ExampleSub() 

188 self.assertIsInstance(sub, self.Example) 

189 self.assertNotIsInstance(sub, Example2) 

190 self.assertTrue(issubclass(ExampleSub, self.Example)) 

191 self.assertFalse(issubclass(ExampleSub, Example2)) 

192 

193 def testConstruction(self): 

194 self.register() 

195 f1 = self.Example(dtype=np.float32) 

196 # Test that numpy dtype objects resolve to their underlying type 

197 f2 = self.Example(dtype=np.dtype(np.float32)) 

198 for f in (f1, f2): 

199 self.assertIsInstance(f, self.Example) 

200 self.assertIsInstance(f, self.ExampleF) 

201 self.assertNotIsInstance(f, self.ExampleD) 

202 

203 with self.assertRaises(TypeError): 

204 self.Example() 

205 with self.assertRaises(TypeError): 

206 self.Example(dtype=np.int32) 

207 

208 def testAttributeCopying(self): 

209 self.register() 

210 f = self.ExampleF() 

211 d = self.ExampleD() 

212 self.assertIs(f.method1(), f) 

213 self.assertIs(d.method1(), d) 

214 self.assertIs(f.method2(), self.ExampleF) 

215 self.assertIs(d.method2(), self.ExampleD) 

216 self.assertIs(self.ExampleF.method2(), self.ExampleF) 

217 self.assertIs(self.ExampleD.method2(), self.ExampleD) 

218 self.assertTrue(f.method3()) 

219 self.assertTrue(d.method3()) 

220 self.assertTrue(self.ExampleF.method3()) 

221 self.assertTrue(self.ExampleD.method3()) 

222 self.assertFalse(f.property1) 

223 self.assertFalse(d.property1) 

224 

225 def testDictBehavior(self): 

226 self.register() 

227 self.assertIn(np.float32, self.Example) 

228 self.assertEqual(self.Example[np.float32], self.ExampleF) 

229 self.assertEqual(set(self.Example.keys()), 

230 set([np.float32, np.float64])) 

231 self.assertEqual(set(self.Example.values()), 

232 set([self.ExampleF, self.ExampleD])) 

233 self.assertEqual(set(self.Example.items()), 

234 set([(np.float32, self.ExampleF), 

235 (np.float64, self.ExampleD)])) 

236 self.assertEqual(len(self.Example), 2) 

237 self.assertEqual(set(iter(self.Example)), set([np.float32, np.float64])) 

238 self.assertEqual(self.Example.get(np.float64), self.ExampleD) 

239 self.assertEqual(self.Example.get(np.int32, False), False) 

240 

241 def testNoInheritedDictBehavior(self): 

242 self.register() 

243 f = self.ExampleF() 

244 with self.assertRaises(Exception): # Py2:AttributeError, Py3:TypeError 

245 len(f) 

246 with self.assertRaises(Exception): # Py2:AttributeError, Py3:TypeError 

247 f["F"] 

248 with self.assertRaises(TypeError): 

249 for x in f: 

250 pass 

251 with self.assertRaises(TypeError): 

252 len(self.ExampleF) 

253 with self.assertRaises(TypeError): 

254 self.ExampleF["F"] 

255 with self.assertRaises(TypeError): 

256 for x in self.ExampleF: 

257 pass 

258 

259 def testAliasUnregistered(self): 

260 with self.assertRaises(ValueError): 

261 self.Example.alias("F", self.ExampleF) 

262 self.assertEqual(len(self.Example), 0) 

263 self.assertEqual(len(self.Example), 0) 

264 

265 def testRegisterDTypeTwice(self): 

266 with self.assertRaises(KeyError): 

267 self.Example.register("F", self.ExampleF) 

268 self.Example.register("F", self.ExampleD) 

269 self.assertEqual(len(self.Example), 1) 

270 

271 def testRegisterTemplateTwice(self): 

272 with self.assertRaises(ValueError): 

273 self.Example.register("F", self.ExampleF) 

274 self.Example.register("D", self.ExampleF) 

275 self.assertEqual(len(self.Example), 1) 

276 

277 

278class TemplateMetaHardTestCase(lsst.utils.tests.TestCase): 

279 """Test TemplateMeta with a mockup of a template with multiple 

280 template parameters. 

281 """ 

282 

283 def setUp(self): 

284 

285 class Example(metaclass=lsst.utils.TemplateMeta): 

286 

287 TEMPLATE_PARAMS = ("d", "u") 

288 TEMPLATE_DEFAULTS = (2, None) 

289 

290 class Example2F: 

291 pass 

292 

293 class Example2D: 

294 pass 

295 

296 class Example3F: 

297 pass 

298 

299 class Example3D: 

300 pass 

301 

302 self.Example = Example 

303 self.Example2F = Example2F 

304 self.Example2D = Example2D 

305 self.Example3F = Example3F 

306 self.Example3D = Example3D 

307 

308 def register(self): 

309 self.Example.register((2, np.float32), self.Example2F) 

310 self.Example.register((2, np.float64), self.Example2D) 

311 self.Example.register((3, np.float32), self.Example3F) 

312 self.Example.register((3, np.float64), self.Example3D) 

313 

314 def alias(self): 

315 self.Example.alias("2F", self.Example2F) 

316 self.Example.alias("2D", self.Example2D) 

317 self.Example.alias("3F", self.Example3F) 

318 self.Example.alias("3D", self.Example3D) 

319 

320 def testCorrectRegistration(self): 

321 self.register() 

322 self.assertEqual(self.Example2F.d, 2) 

323 self.assertEqual(self.Example2F.u, np.float32) 

324 self.assertEqual(self.Example2D.d, 2) 

325 self.assertEqual(self.Example2D.u, np.float64) 

326 self.assertEqual(self.Example3F.d, 3) 

327 self.assertEqual(self.Example3F.u, np.float32) 

328 self.assertEqual(self.Example3D.d, 3) 

329 self.assertEqual(self.Example3D.u, np.float64) 

330 self.assertIn((2, np.float32), self.Example) 

331 self.assertIn((2, np.float64), self.Example) 

332 self.assertIn((3, np.float32), self.Example) 

333 self.assertIn((3, np.float64), self.Example) 

334 self.assertEqual(self.Example[2, np.float32], self.Example2F) 

335 self.assertEqual(self.Example[2, np.float64], self.Example2D) 

336 self.assertEqual(self.Example[3, np.float32], self.Example3F) 

337 self.assertEqual(self.Example[3, np.float64], self.Example3D) 

338 

339 def testAliases(self): 

340 self.register() 

341 self.alias() 

342 self.assertEqual(self.Example2F.d, 2) 

343 self.assertEqual(self.Example2F.u, np.float32) 

344 self.assertEqual(self.Example2D.d, 2) 

345 self.assertEqual(self.Example2D.u, np.float64) 

346 self.assertEqual(self.Example3F.d, 3) 

347 self.assertEqual(self.Example3F.u, np.float32) 

348 self.assertEqual(self.Example3D.d, 3) 

349 self.assertEqual(self.Example3D.u, np.float64) 

350 self.assertIn("2F", self.Example) 

351 self.assertIn("2D", self.Example) 

352 self.assertIn("3F", self.Example) 

353 self.assertIn("3D", self.Example) 

354 self.assertEqual(self.Example["2F"], self.Example2F) 

355 self.assertEqual(self.Example["2D"], self.Example2D) 

356 self.assertEqual(self.Example["3F"], self.Example3F) 

357 self.assertEqual(self.Example["3D"], self.Example3D) 

358 

359 def testInheritanceHooks(self): 

360 self.register() 

361 self.assertTrue(issubclass(self.Example2F, self.Example)) 

362 self.assertTrue(issubclass(self.Example3D, self.Example)) 

363 f = self.Example2F() 

364 d = self.Example3D() 

365 self.assertIsInstance(f, self.Example) 

366 self.assertIsInstance(d, self.Example) 

367 self.assertEqual(set(self.Example.__subclasses__()), 

368 set([self.Example2F, self.Example2D, 

369 self.Example3F, self.Example3D])) 

370 

371 def testConstruction(self): 

372 self.register() 

373 f = self.Example(u=np.float32) 

374 self.assertIsInstance(f, self.Example) 

375 self.assertIsInstance(f, self.Example2F) 

376 with self.assertRaises(TypeError): 

377 self.Example() 

378 with self.assertRaises(TypeError): 

379 self.Example(u=np.int32, d=1) 

380 

381 def testDictBehavior(self): 

382 self.register() 

383 self.assertIn((2, np.float32), self.Example) 

384 self.assertEqual(self.Example[2, np.float32], self.Example2F) 

385 self.assertEqual(set(self.Example.keys()), 

386 set([(2, np.float32), (2, np.float64), 

387 (3, np.float32), (3, np.float64)])) 

388 self.assertEqual(set(self.Example.values()), 

389 set([self.Example2F, self.Example2D, 

390 self.Example3F, self.Example3D])) 

391 self.assertEqual(set(self.Example.items()), 

392 set([((2, np.float32), self.Example2F), 

393 ((2, np.float64), self.Example2D), 

394 ((3, np.float32), self.Example3F), 

395 ((3, np.float64), self.Example3D)])) 

396 self.assertEqual(len(self.Example), 4) 

397 self.assertEqual(set(iter(self.Example)), 

398 set([(2, np.float32), (2, np.float64), 

399 (3, np.float32), (3, np.float64)])) 

400 self.assertEqual(self.Example.get((3, np.float64)), self.Example3D) 

401 self.assertEqual(self.Example.get((2, np.int32), False), False) 

402 

403 def testRegisterBadKey(self): 

404 with self.assertRaises(ValueError): 

405 self.Example.register("F", self.Example2F) 

406 

407 def testRegisterDTypeTwice(self): 

408 with self.assertRaises(KeyError): 

409 self.Example.register((2, "F"), self.Example2F) 

410 self.Example.register((2, "F"), self.Example2D) 

411 self.assertEqual(len(self.Example), 1) 

412 

413 def testRegisterTemplateTwice(self): 

414 with self.assertRaises(ValueError): 

415 self.Example.register((2, "F"), self.Example2F) 

416 self.Example.register((2, "D"), self.Example2F) 

417 self.assertEqual(len(self.Example), 1) 

418 

419 

420class TestDefaultMethodCopying(lsst.utils.tests.TestCase): 

421 """ Test to determine if static and class methods from a class which is 

422 registered as a default type in a type ABC are properly copied. 

423 """ 

424 def setUp(self): 

425 class Example(metaclass=lsst.utils.TemplateMeta): 

426 

427 TEMPLATE_PARAMS = ("dtype",) 

428 TEMPLATE_DEFAULTS = (np.float32,) 

429 

430 class ExampleF: 

431 @staticmethod 

432 def staticCall(): 

433 return 6 

434 

435 @classmethod 

436 def classCall(cls): 

437 return cls 

438 

439 def regularCall(self): 

440 return self 

441 

442 class ExampleI: 

443 @staticmethod 

444 def notTransferedStaticCall(): 

445 return 8 

446 

447 @classmethod 

448 def notTransferedClassCall(cls): 

449 return cls 

450 

451 # Add in a built in function to ExampleF to mimic how pybind11 treats 

452 # static methods from c++ 

453 setattr(ExampleF, 'pow', pow) 

454 

455 Example.register(np.float32, ExampleF) 

456 Example.register(np.int32, ExampleI) 

457 self.Example = Example 

458 self.ExampleF = ExampleF 

459 self.ExampleI = ExampleI 

460 

461 def testMethodCopyForDefaultType(self): 

462 # Check that the methods for the default type were transfered and that 

463 # the regular method was not 

464 self.assertTrue(hasattr(self.Example, 'staticCall')) 

465 self.assertTrue(hasattr(self.Example, 'pow')) 

466 self.assertTrue(hasattr(self.Example, 'classCall')) 

467 self.assertFalse(hasattr(self.Example, 'regularCall')) 

468 

469 # Verify the default static and class method defaults return the 

470 # correct values 

471 self.assertEqual(self.Example.staticCall(), 6) 

472 self.assertEqual(self.Example.pow(2, 2), 4) 

473 self.assertIs(self.Example.classCall(), self.ExampleF) 

474 

475 # Verify static and class methods for non default keys are not 

476 # transfered 

477 self.assertFalse(hasattr(self.Example, "notTransferedStaticCall")) 

478 self.assertFalse(hasattr(self.Example, "notTransferedClassCall")) 

479 

480 

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

482 unittest.main()