Coverage for tests/test_wrappers.py: 13%
350 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 02:14 -0700
« prev ^ index » next coverage.py v6.4.2, created at 2022-08-04 02:14 -0700
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.
12import unittest
14import lsst.utils
15import lsst.utils.tests
16import numpy as np
19class MockClass: # continued class needs to be at module scope
20 def method1(self):
21 return self
23 @classmethod
24 def method2(cls):
25 return cls
27 @staticmethod
28 def method3():
29 return True
31 @property
32 def property1(self):
33 return False
36class DecoratorsTestCase(lsst.utils.tests.TestCase):
37 def setUp(self):
38 @lsst.utils.continueClass
39 class MockClass:
40 def method1a(self):
41 return self
43 @classmethod
44 def method2a(cls):
45 return cls
47 @staticmethod
48 def method3a():
49 return True
51 @property
52 def property1a(self):
53 return False
55 @lsst.utils.inClass(MockClass)
56 def method1b(self):
57 return self
59 @lsst.utils.inClass(MockClass)
60 @classmethod
61 def method2b(cls):
62 return cls
64 @lsst.utils.inClass(MockClass)
65 @staticmethod
66 def method3b():
67 return True
69 @lsst.utils.inClass(MockClass)
70 @property
71 def property1b(self):
72 return False
74 def testAttributeCopying(self):
75 x = MockClass()
76 self.assertIs(x.method1(), x)
77 self.assertIs(x.method1a(), x)
78 self.assertIs(x.method1b(), x)
79 self.assertIs(x.method2(), MockClass)
80 self.assertIs(x.method2a(), MockClass)
81 self.assertIs(x.method2b(), MockClass)
82 self.assertIs(MockClass.method2(), MockClass)
83 self.assertIs(MockClass.method2a(), MockClass)
84 self.assertIs(MockClass.method2b(), MockClass)
85 self.assertTrue(x.method3())
86 self.assertTrue(x.method3a())
87 self.assertTrue(x.method3b())
88 self.assertTrue(MockClass.method3())
89 self.assertTrue(MockClass.method3a())
90 self.assertTrue(MockClass.method3b())
91 self.assertFalse(x.property1)
92 self.assertFalse(x.property1a)
93 self.assertFalse(x.property1b)
96class TemplateMetaSimpleTestCase(lsst.utils.tests.TestCase):
97 """Test TemplateMeta on a mockup of a template with a single dtype
98 template parameter.
99 """
101 def setUp(self):
102 class Example(metaclass=lsst.utils.TemplateMeta):
103 def method1(self):
104 return self
106 @classmethod
107 def method2(cls):
108 return cls
110 @staticmethod
111 def method3():
112 return True
114 @property
115 def property1(self):
116 return False
118 class ExampleF:
119 pass
121 class ExampleD:
122 pass
124 self.Example = Example
125 self.ExampleF = ExampleF
126 self.ExampleD = ExampleD
128 def register(self):
129 self.Example.register(np.float32, self.ExampleF)
130 self.Example.register(np.float64, self.ExampleD)
132 def alias(self):
133 self.Example.alias("F", self.ExampleF)
134 self.Example.alias("D", self.ExampleD)
136 def testCorrectRegistration(self):
137 self.register()
138 self.assertEqual(self.ExampleF.dtype, np.float32)
139 self.assertEqual(self.ExampleD.dtype, np.float64)
140 self.assertIn(np.float32, self.Example)
141 self.assertIn(np.float64, self.Example)
142 self.assertEqual(self.Example[np.float32], self.ExampleF)
143 self.assertEqual(self.Example[np.float64], self.ExampleD)
145 def testAliases(self):
146 self.register()
147 self.alias()
148 self.assertEqual(self.ExampleF.dtype, np.float32)
149 self.assertEqual(self.ExampleD.dtype, np.float64)
150 self.assertIn("F", self.Example)
151 self.assertIn("D", self.Example)
152 self.assertEqual(self.Example["F"], self.ExampleF)
153 self.assertEqual(self.Example["D"], self.ExampleD)
154 self.assertEqual(self.Example["F"], self.Example[np.float32])
155 self.assertEqual(self.Example["D"], self.Example[np.float64])
157 def testInheritanceHooks(self):
158 self.register()
159 self.assertTrue(issubclass(self.ExampleF, self.Example))
160 self.assertTrue(issubclass(self.ExampleD, self.Example))
161 f = self.ExampleF()
162 d = self.ExampleD()
163 self.assertIsInstance(f, self.Example)
164 self.assertIsInstance(d, self.Example)
165 self.assertEqual(set(self.Example.__subclasses__()), set([self.ExampleF, self.ExampleD]))
167 # To test fallback code path, ensure that there are multiple
168 # examples to check.
169 class ExampleSub(self.ExampleD):
170 # A subclass that is not itself registered.
171 pass
173 class Example2(metaclass=lsst.utils.TemplateMeta):
174 # A new independent class.
175 pass
177 class Example2I:
178 # Something that will be registered in independent hierarchy.
179 pass
181 Example2.register(np.int32, Example2I)
183 sub = ExampleSub()
184 self.assertIsInstance(sub, self.Example)
185 self.assertNotIsInstance(sub, Example2)
186 self.assertTrue(issubclass(ExampleSub, self.Example))
187 self.assertFalse(issubclass(ExampleSub, Example2))
189 def testConstruction(self):
190 self.register()
191 f1 = self.Example(dtype=np.float32)
192 # Test that numpy dtype objects resolve to their underlying type
193 f2 = self.Example(dtype=np.dtype(np.float32))
194 for f in (f1, f2):
195 self.assertIsInstance(f, self.Example)
196 self.assertIsInstance(f, self.ExampleF)
197 self.assertNotIsInstance(f, self.ExampleD)
199 with self.assertRaises(TypeError):
200 self.Example()
201 with self.assertRaises(TypeError):
202 self.Example(dtype=np.int32)
204 def testAttributeCopying(self):
205 self.register()
206 f = self.ExampleF()
207 d = self.ExampleD()
208 self.assertIs(f.method1(), f)
209 self.assertIs(d.method1(), d)
210 self.assertIs(f.method2(), self.ExampleF)
211 self.assertIs(d.method2(), self.ExampleD)
212 self.assertIs(self.ExampleF.method2(), self.ExampleF)
213 self.assertIs(self.ExampleD.method2(), self.ExampleD)
214 self.assertTrue(f.method3())
215 self.assertTrue(d.method3())
216 self.assertTrue(self.ExampleF.method3())
217 self.assertTrue(self.ExampleD.method3())
218 self.assertFalse(f.property1)
219 self.assertFalse(d.property1)
221 def testDictBehavior(self):
222 self.register()
223 self.assertIn(np.float32, self.Example)
224 self.assertEqual(self.Example[np.float32], self.ExampleF)
225 self.assertEqual(set(self.Example.keys()), set([np.float32, np.float64]))
226 self.assertEqual(set(self.Example.values()), set([self.ExampleF, self.ExampleD]))
227 self.assertEqual(
228 set(self.Example.items()), set([(np.float32, self.ExampleF), (np.float64, self.ExampleD)])
229 )
230 self.assertEqual(len(self.Example), 2)
231 self.assertEqual(set(iter(self.Example)), set([np.float32, np.float64]))
232 self.assertEqual(self.Example.get(np.float64), self.ExampleD)
233 self.assertEqual(self.Example.get(np.int32, False), False)
235 def testNoInheritedDictBehavior(self):
236 self.register()
237 f = self.ExampleF()
238 with self.assertRaises(Exception): # Py2:AttributeError, Py3:TypeError
239 len(f)
240 with self.assertRaises(Exception): # Py2:AttributeError, Py3:TypeError
241 f["F"]
242 with self.assertRaises(TypeError):
243 for x in f:
244 pass
245 with self.assertRaises(TypeError):
246 len(self.ExampleF)
247 with self.assertRaises(TypeError):
248 self.ExampleF["F"]
249 with self.assertRaises(TypeError):
250 for x in self.ExampleF:
251 pass
253 def testAliasUnregistered(self):
254 with self.assertRaises(ValueError):
255 self.Example.alias("F", self.ExampleF)
256 self.assertEqual(len(self.Example), 0)
257 self.assertEqual(len(self.Example), 0)
259 def testRegisterDTypeTwice(self):
260 with self.assertRaises(KeyError):
261 self.Example.register("F", self.ExampleF)
262 self.Example.register("F", self.ExampleD)
263 self.assertEqual(len(self.Example), 1)
265 def testRegisterTemplateTwice(self):
266 with self.assertRaises(ValueError):
267 self.Example.register("F", self.ExampleF)
268 self.Example.register("D", self.ExampleF)
269 self.assertEqual(len(self.Example), 1)
272class TemplateMetaHardTestCase(lsst.utils.tests.TestCase):
273 """Test TemplateMeta with a mockup of a template with multiple
274 template parameters.
275 """
277 def setUp(self):
278 class Example(metaclass=lsst.utils.TemplateMeta):
280 TEMPLATE_PARAMS = ("d", "u")
281 TEMPLATE_DEFAULTS = (2, None)
283 class Example2F:
284 pass
286 class Example2D:
287 pass
289 class Example3F:
290 pass
292 class Example3D:
293 pass
295 self.Example = Example
296 self.Example2F = Example2F
297 self.Example2D = Example2D
298 self.Example3F = Example3F
299 self.Example3D = Example3D
301 def register(self):
302 self.Example.register((2, np.float32), self.Example2F)
303 self.Example.register((2, np.float64), self.Example2D)
304 self.Example.register((3, np.float32), self.Example3F)
305 self.Example.register((3, np.float64), self.Example3D)
307 def alias(self):
308 self.Example.alias("2F", self.Example2F)
309 self.Example.alias("2D", self.Example2D)
310 self.Example.alias("3F", self.Example3F)
311 self.Example.alias("3D", self.Example3D)
313 def testCorrectRegistration(self):
314 self.register()
315 self.assertEqual(self.Example2F.d, 2)
316 self.assertEqual(self.Example2F.u, np.float32)
317 self.assertEqual(self.Example2D.d, 2)
318 self.assertEqual(self.Example2D.u, np.float64)
319 self.assertEqual(self.Example3F.d, 3)
320 self.assertEqual(self.Example3F.u, np.float32)
321 self.assertEqual(self.Example3D.d, 3)
322 self.assertEqual(self.Example3D.u, np.float64)
323 self.assertIn((2, np.float32), self.Example)
324 self.assertIn((2, np.float64), self.Example)
325 self.assertIn((3, np.float32), self.Example)
326 self.assertIn((3, np.float64), self.Example)
327 self.assertEqual(self.Example[2, np.float32], self.Example2F)
328 self.assertEqual(self.Example[2, np.float64], self.Example2D)
329 self.assertEqual(self.Example[3, np.float32], self.Example3F)
330 self.assertEqual(self.Example[3, np.float64], self.Example3D)
332 def testAliases(self):
333 self.register()
334 self.alias()
335 self.assertEqual(self.Example2F.d, 2)
336 self.assertEqual(self.Example2F.u, np.float32)
337 self.assertEqual(self.Example2D.d, 2)
338 self.assertEqual(self.Example2D.u, np.float64)
339 self.assertEqual(self.Example3F.d, 3)
340 self.assertEqual(self.Example3F.u, np.float32)
341 self.assertEqual(self.Example3D.d, 3)
342 self.assertEqual(self.Example3D.u, np.float64)
343 self.assertIn("2F", self.Example)
344 self.assertIn("2D", self.Example)
345 self.assertIn("3F", self.Example)
346 self.assertIn("3D", self.Example)
347 self.assertEqual(self.Example["2F"], self.Example2F)
348 self.assertEqual(self.Example["2D"], self.Example2D)
349 self.assertEqual(self.Example["3F"], self.Example3F)
350 self.assertEqual(self.Example["3D"], self.Example3D)
352 def testInheritanceHooks(self):
353 self.register()
354 self.assertTrue(issubclass(self.Example2F, self.Example))
355 self.assertTrue(issubclass(self.Example3D, self.Example))
356 f = self.Example2F()
357 d = self.Example3D()
358 self.assertIsInstance(f, self.Example)
359 self.assertIsInstance(d, self.Example)
360 self.assertEqual(
361 set(self.Example.__subclasses__()),
362 set([self.Example2F, self.Example2D, self.Example3F, self.Example3D]),
363 )
365 def testConstruction(self):
366 self.register()
367 f = self.Example(u=np.float32)
368 self.assertIsInstance(f, self.Example)
369 self.assertIsInstance(f, self.Example2F)
370 with self.assertRaises(TypeError):
371 self.Example()
372 with self.assertRaises(TypeError):
373 self.Example(u=np.int32, d=1)
375 def testDictBehavior(self):
376 self.register()
377 self.assertIn((2, np.float32), self.Example)
378 self.assertEqual(self.Example[2, np.float32], self.Example2F)
379 self.assertEqual(
380 set(self.Example.keys()),
381 set([(2, np.float32), (2, np.float64), (3, np.float32), (3, np.float64)]),
382 )
383 self.assertEqual(
384 set(self.Example.values()), set([self.Example2F, self.Example2D, self.Example3F, self.Example3D])
385 )
386 self.assertEqual(
387 set(self.Example.items()),
388 set(
389 [
390 ((2, np.float32), self.Example2F),
391 ((2, np.float64), self.Example2D),
392 ((3, np.float32), self.Example3F),
393 ((3, np.float64), self.Example3D),
394 ]
395 ),
396 )
397 self.assertEqual(len(self.Example), 4)
398 self.assertEqual(
399 set(iter(self.Example)), set([(2, np.float32), (2, np.float64), (3, np.float32), (3, np.float64)])
400 )
401 self.assertEqual(self.Example.get((3, np.float64)), self.Example3D)
402 self.assertEqual(self.Example.get((2, np.int32), False), False)
404 def testRegisterBadKey(self):
405 with self.assertRaises(ValueError):
406 self.Example.register("F", self.Example2F)
408 def testRegisterDTypeTwice(self):
409 with self.assertRaises(KeyError):
410 self.Example.register((2, "F"), self.Example2F)
411 self.Example.register((2, "F"), self.Example2D)
412 self.assertEqual(len(self.Example), 1)
414 def testRegisterTemplateTwice(self):
415 with self.assertRaises(ValueError):
416 self.Example.register((2, "F"), self.Example2F)
417 self.Example.register((2, "D"), self.Example2F)
418 self.assertEqual(len(self.Example), 1)
421class TestDefaultMethodCopying(lsst.utils.tests.TestCase):
422 """Test to determine if static and class methods from a class which is
423 registered as a default type in a type ABC are properly copied.
424 """
426 def setUp(self):
427 class Example(metaclass=lsst.utils.TemplateMeta):
429 TEMPLATE_PARAMS = ("dtype",)
430 TEMPLATE_DEFAULTS = (np.float32,)
432 class ExampleF:
433 @staticmethod
434 def staticCall():
435 return 6
437 @classmethod
438 def classCall(cls):
439 return cls
441 def regularCall(self):
442 return self
444 class ExampleI:
445 @staticmethod
446 def notTransferedStaticCall():
447 return 8
449 @classmethod
450 def notTransferedClassCall(cls):
451 return cls
453 # Add in a built in function to ExampleF to mimic how pybind11 treats
454 # static methods from c++
455 setattr(ExampleF, "pow", pow)
457 Example.register(np.float32, ExampleF)
458 Example.register(np.int32, ExampleI)
459 self.Example = Example
460 self.ExampleF = ExampleF
461 self.ExampleI = ExampleI
463 def testMethodCopyForDefaultType(self):
464 # Check that the methods for the default type were transfered and that
465 # the regular method was not
466 self.assertTrue(hasattr(self.Example, "staticCall"))
467 self.assertTrue(hasattr(self.Example, "pow"))
468 self.assertTrue(hasattr(self.Example, "classCall"))
469 self.assertFalse(hasattr(self.Example, "regularCall"))
471 # Verify the default static and class method defaults return the
472 # correct values
473 self.assertEqual(self.Example.staticCall(), 6)
474 self.assertEqual(self.Example.pow(2, 2), 4)
475 self.assertIs(self.Example.classCall(), self.ExampleF)
477 # Verify static and class methods for non default keys are not
478 # transfered
479 self.assertFalse(hasattr(self.Example, "notTransferedStaticCall"))
480 self.assertFalse(hasattr(self.Example, "notTransferedClassCall"))
483if __name__ == "__main__": 483 ↛ 484line 483 didn't jump to line 484, because the condition on line 483 was never true
484 unittest.main()