Hide keyboard shortcuts

Hot-keys 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

1# 

2# Developed for the LSST Data Management System. 

3# This product includes software developed by the LSST Project 

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

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

6# for details of code ownership. 

7# 

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

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

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

11# (at your option) any later version. 

12# 

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

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

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

16# GNU General Public License for more details. 

17# 

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

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

20# 

21 

22import numpy as np 

23import unittest 

24import lsst.utils.tests 

25import lsst.utils 

26 

27 

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

29 

30 def method1(self): 

31 return self 

32 

33 @classmethod 

34 def method2(cls): 

35 return cls 

36 

37 @staticmethod 

38 def method3(): 

39 return True 

40 

41 @property 

42 def property1(self): 

43 return False 

44 

45 

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

47 

48 def setUp(self): 

49 @lsst.utils.continueClass 

50 class MockClass: 

51 

52 def method1a(self): 

53 return self 

54 

55 @classmethod 

56 def method2a(cls): 

57 return cls 

58 

59 @staticmethod 

60 def method3a(): 

61 return True 

62 

63 @property 

64 def property1a(self): 

65 return False 

66 

67 @lsst.utils.inClass(MockClass) 

68 def method1b(self): 

69 return self 

70 

71 @lsst.utils.inClass(MockClass) 

72 @classmethod 

73 def method2b(cls): 

74 return cls 

75 

76 @lsst.utils.inClass(MockClass) 

77 @staticmethod 

78 def method3b(): 

79 return True 

80 

81 @lsst.utils.inClass(MockClass) 

82 @property 

83 def property1b(self): 

84 return False 

85 

86 def testAttributeCopying(self): 

87 x = MockClass() 

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

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

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

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

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

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

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

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

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

97 self.assertTrue(x.method3()) 

98 self.assertTrue(x.method3a()) 

99 self.assertTrue(x.method3b()) 

100 self.assertTrue(MockClass.method3()) 

101 self.assertTrue(MockClass.method3a()) 

102 self.assertTrue(MockClass.method3b()) 

103 self.assertFalse(x.property1) 

104 self.assertFalse(x.property1a) 

105 self.assertFalse(x.property1b) 

106 

107 

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

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

110 template parameter. 

111 """ 

112 

113 def setUp(self): 

114 

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

116 

117 def method1(self): 

118 return self 

119 

120 @classmethod 

121 def method2(cls): 

122 return cls 

123 

124 @staticmethod 

125 def method3(): 

126 return True 

127 

128 @property 

129 def property1(self): 

130 return False 

131 

132 class ExampleF: 

133 pass 

134 

135 class ExampleD: 

136 pass 

137 

138 self.Example = Example 

139 self.ExampleF = ExampleF 

140 self.ExampleD = ExampleD 

141 

142 def register(self): 

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

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

145 

146 def alias(self): 

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

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

149 

150 def testCorrectRegistration(self): 

151 self.register() 

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

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

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

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

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

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

158 

159 def testAliases(self): 

160 self.register() 

161 self.alias() 

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

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

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

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

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

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

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

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

170 

171 def testInheritanceHooks(self): 

172 self.register() 

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

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

175 f = self.ExampleF() 

176 d = self.ExampleD() 

177 self.assertIsInstance(f, self.Example) 

178 self.assertIsInstance(d, self.Example) 

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

180 

181 def testConstruction(self): 

182 self.register() 

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

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

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

186 for f in (f1, f2): 

187 self.assertIsInstance(f, self.Example) 

188 self.assertIsInstance(f, self.ExampleF) 

189 self.assertNotIsInstance(f, self.ExampleD) 

190 

191 with self.assertRaises(TypeError): 

192 self.Example() 

193 with self.assertRaises(TypeError): 

194 self.Example(dtype=np.int32) 

195 

196 def testAttributeCopying(self): 

197 self.register() 

198 f = self.ExampleF() 

199 d = self.ExampleD() 

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

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

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

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

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

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

206 self.assertTrue(f.method3()) 

207 self.assertTrue(d.method3()) 

208 self.assertTrue(self.ExampleF.method3()) 

209 self.assertTrue(self.ExampleD.method3()) 

210 self.assertFalse(f.property1) 

211 self.assertFalse(d.property1) 

212 

213 def testDictBehavior(self): 

214 self.register() 

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

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

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

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

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

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

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

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

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

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

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

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

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

228 

229 def testNoInheritedDictBehavior(self): 

230 self.register() 

231 f = self.ExampleF() 

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

233 len(f) 

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

235 f["F"] 

236 with self.assertRaises(TypeError): 

237 for x in f: 

238 pass 

239 with self.assertRaises(TypeError): 

240 len(self.ExampleF) 

241 with self.assertRaises(TypeError): 

242 self.ExampleF["F"] 

243 with self.assertRaises(TypeError): 

244 for x in self.ExampleF: 

245 pass 

246 

247 def testAliasUnregistered(self): 

248 with self.assertRaises(ValueError): 

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

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

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

252 

253 def testRegisterDTypeTwice(self): 

254 with self.assertRaises(KeyError): 

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

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

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

258 

259 def testRegisterTemplateTwice(self): 

260 with self.assertRaises(ValueError): 

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

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

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

264 

265 

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

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

268 template parameters. 

269 """ 

270 

271 def setUp(self): 

272 

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

274 

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

276 TEMPLATE_DEFAULTS = (2, None) 

277 

278 class Example2F: 

279 pass 

280 

281 class Example2D: 

282 pass 

283 

284 class Example3F: 

285 pass 

286 

287 class Example3D: 

288 pass 

289 

290 self.Example = Example 

291 self.Example2F = Example2F 

292 self.Example2D = Example2D 

293 self.Example3F = Example3F 

294 self.Example3D = Example3D 

295 

296 def register(self): 

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

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

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

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

301 

302 def alias(self): 

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

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

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

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

307 

308 def testCorrectRegistration(self): 

309 self.register() 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

326 

327 def testAliases(self): 

328 self.register() 

329 self.alias() 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

346 

347 def testInheritanceHooks(self): 

348 self.register() 

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

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

351 f = self.Example2F() 

352 d = self.Example3D() 

353 self.assertIsInstance(f, self.Example) 

354 self.assertIsInstance(d, self.Example) 

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

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

357 self.Example3F, self.Example3D])) 

358 

359 def testConstruction(self): 

360 self.register() 

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

362 self.assertIsInstance(f, self.Example) 

363 self.assertIsInstance(f, self.Example2F) 

364 with self.assertRaises(TypeError): 

365 self.Example() 

366 with self.assertRaises(TypeError): 

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

368 

369 def testDictBehavior(self): 

370 self.register() 

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

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

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

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

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

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

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

378 self.Example3F, self.Example3D])) 

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

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

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

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

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

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

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

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

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

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

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

390 

391 def testRegisterBadKey(self): 

392 with self.assertRaises(ValueError): 

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

394 

395 def testRegisterDTypeTwice(self): 

396 with self.assertRaises(KeyError): 

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

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

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

400 

401 def testRegisterTemplateTwice(self): 

402 with self.assertRaises(ValueError): 

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

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

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

406 

407 

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

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

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

411 """ 

412 def setUp(self): 

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

414 

415 TEMPLATE_PARAMS = ("dtype",) 

416 TEMPLATE_DEFAULTS = (np.float32,) 

417 

418 class ExampleF: 

419 @staticmethod 

420 def staticCall(): 

421 return 6 

422 

423 @classmethod 

424 def classCall(cls): 

425 return cls 

426 

427 def regularCall(self): 

428 return self 

429 

430 class ExampleI: 

431 @staticmethod 

432 def notTransferedStaticCall(): 

433 return 8 

434 

435 @classmethod 

436 def notTransferedClassCall(cls): 

437 return cls 

438 

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

440 # static methods from c++ 

441 setattr(ExampleF, 'pow', pow) 

442 

443 Example.register(np.float32, ExampleF) 

444 Example.register(np.int32, ExampleI) 

445 self.Example = Example 

446 self.ExampleF = ExampleF 

447 self.ExampleI = ExampleI 

448 

449 def testMethodCopyForDefaultType(self): 

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

451 # the regular method was not 

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

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

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

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

456 

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

458 # correct values 

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

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

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

462 

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

464 # transfered 

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

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

467 

468 

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

470 unittest.main()