LEFT | RIGHT |
1 # Copyright 2007 Google, Inc. All Rights Reserved. | 1 # Copyright 2007 Google, Inc. All Rights Reserved. |
2 # Licensed to PSF under a Contributor Agreement. | 2 # Licensed to PSF under a Contributor Agreement. |
3 | 3 |
4 """Unit tests for abc.py.""" | 4 """Unit tests for abc.py.""" |
5 | 5 |
6 import unittest | 6 import unittest |
7 from test import support | 7 from test import support |
8 | 8 |
9 import abc | 9 import abc |
10 from inspect import isabstract | 10 from inspect import isabstract |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 def test_abstractstaticmethod_basics(self): | 50 def test_abstractstaticmethod_basics(self): |
51 @abc.abstractstaticmethod | 51 @abc.abstractstaticmethod |
52 def foo(): pass | 52 def foo(): pass |
53 self.assertTrue(foo.__isabstractmethod__) | 53 self.assertTrue(foo.__isabstractmethod__) |
54 @staticmethod | 54 @staticmethod |
55 def bar(): pass | 55 def bar(): pass |
56 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) | 56 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) |
57 | 57 |
58 class C(metaclass=abc.ABCMeta): | 58 class C(metaclass=abc.ABCMeta): |
59 @abc.abstractstaticmethod | 59 @abc.abstractstaticmethod |
| 60 def foo(): return 3 |
| 61 self.assertRaises(TypeError, C) |
| 62 class D(C): |
| 63 @staticmethod |
| 64 def foo(): return 4 |
| 65 self.assertEqual(D.foo(), 4) |
| 66 self.assertEqual(D().foo(), 4) |
| 67 |
| 68 |
| 69 class TestABC(unittest.TestCase): |
| 70 |
| 71 def test_ABC_helper(self): |
| 72 # create an ABC using the helper class and perform basic checks |
| 73 class C(abc.ABC): |
| 74 @classmethod |
| 75 @abc.abstractmethod |
| 76 def foo(cls): return cls.__name__ |
| 77 self.assertEqual(type(C), abc.ABCMeta) |
| 78 self.assertRaises(TypeError, C) |
| 79 class D(C): |
| 80 @classmethod |
| 81 def foo(cls): return super().foo() |
| 82 self.assertEqual(D.foo(), 'D') |
| 83 |
| 84 def test_abstractmethod_basics(self): |
| 85 @abc.abstractmethod |
| 86 def foo(self): pass |
| 87 self.assertTrue(foo.__isabstractmethod__) |
| 88 def bar(self): pass |
| 89 self.assertFalse(hasattr(bar, "__isabstractmethod__")) |
| 90 |
| 91 def test_abstractproperty_basics(self): |
| 92 @property |
| 93 @abc.abstractmethod |
| 94 def foo(self): pass |
| 95 self.assertTrue(foo.__isabstractmethod__) |
| 96 def bar(self): pass |
| 97 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) |
| 98 |
| 99 class C(metaclass=abc.ABCMeta): |
| 100 @property |
| 101 @abc.abstractmethod |
| 102 def foo(self): return 3 |
| 103 self.assertRaises(TypeError, C) |
| 104 class D(C): |
| 105 @C.foo.getter |
| 106 def foo(self): return super().foo |
| 107 self.assertEqual(D().foo, 3) |
| 108 |
| 109 def test_abstractclassmethod_basics(self): |
| 110 @classmethod |
| 111 @abc.abstractmethod |
| 112 def foo(cls): pass |
| 113 self.assertTrue(foo.__isabstractmethod__) |
| 114 @classmethod |
| 115 def bar(cls): pass |
| 116 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) |
| 117 |
| 118 class C(metaclass=abc.ABCMeta): |
| 119 @classmethod |
| 120 @abc.abstractmethod |
| 121 def foo(cls): return cls.__name__ |
| 122 self.assertRaises(TypeError, C) |
| 123 class D(C): |
| 124 @classmethod |
| 125 def foo(cls): return super().foo() |
| 126 self.assertEqual(D.foo(), 'D') |
| 127 self.assertEqual(D().foo(), 'D') |
| 128 |
| 129 def test_abstractstaticmethod_basics(self): |
| 130 @staticmethod |
| 131 @abc.abstractmethod |
| 132 def foo(): pass |
| 133 self.assertTrue(foo.__isabstractmethod__) |
| 134 @staticmethod |
| 135 def bar(): pass |
| 136 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) |
| 137 |
| 138 class C(metaclass=abc.ABCMeta): |
| 139 @staticmethod |
| 140 @abc.abstractmethod |
60 def foo(): return 3 | 141 def foo(): return 3 |
61 self.assertRaises(TypeError, C) | 142 self.assertRaises(TypeError, C) |
62 class D(C): | 143 class D(C): |
63 @staticmethod | 144 @staticmethod |
64 def foo(): return 4 | 145 def foo(): return 4 |
65 self.assertEqual(D.foo(), 4) | 146 self.assertEqual(D.foo(), 4) |
66 self.assertEqual(D().foo(), 4) | 147 self.assertEqual(D().foo(), 4) |
67 | 148 |
68 def test_abstractmethod_integration(self): | 149 def test_abstractmethod_integration(self): |
69 for abstractthing in [abc.abstractmethod, abc.abstractproperty, | 150 for abstractthing in [abc.abstractmethod, abc.abstractproperty, |
(...skipping 16 matching lines...) Expand all Loading... |
86 self.assertEqual(E.__abstractmethods__, set()) | 167 self.assertEqual(E.__abstractmethods__, set()) |
87 E() # now foo is concrete, too | 168 E() # now foo is concrete, too |
88 self.assertFalse(isabstract(E)) | 169 self.assertFalse(isabstract(E)) |
89 class F(E): | 170 class F(E): |
90 @abstractthing | 171 @abstractthing |
91 def bar(self): pass # abstract override of concrete | 172 def bar(self): pass # abstract override of concrete |
92 self.assertEqual(F.__abstractmethods__, {"bar"}) | 173 self.assertEqual(F.__abstractmethods__, {"bar"}) |
93 self.assertRaises(TypeError, F) # because bar is abstract now | 174 self.assertRaises(TypeError, F) # because bar is abstract now |
94 self.assertTrue(isabstract(F)) | 175 self.assertTrue(isabstract(F)) |
95 | 176 |
96 | |
97 class TestABC(unittest.TestCase): | |
98 | |
99 def test_abstractmethod_basics(self): | |
100 @abc.abstractmethod | |
101 def foo(self): pass | |
102 self.assertTrue(foo.__isabstractmethod__) | |
103 def bar(self): pass | |
104 self.assertFalse(hasattr(bar, "__isabstractmethod__")) | |
105 | |
106 def test_abstractproperty_basics(self): | |
107 @property | |
108 @abc.abstractmethod | |
109 def foo(self): pass | |
110 self.assertTrue(foo.__isabstractmethod__) | |
111 def bar(self): pass | |
112 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) | |
113 | |
114 class C(metaclass=abc.ABCMeta): | |
115 @property | |
116 @abc.abstractmethod | |
117 def foo(self): return 3 | |
118 self.assertRaises(TypeError, C) | |
119 class D(C): | |
120 @C.foo.getter | |
121 def foo(self): return super().foo | |
122 self.assertEqual(D().foo, 3) | |
123 | |
124 def test_abstractclassmethod_basics(self): | |
125 @classmethod | |
126 @abc.abstractmethod | |
127 def foo(cls): pass | |
128 self.assertTrue(foo.__isabstractmethod__) | |
129 @classmethod | |
130 def bar(cls): pass | |
131 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) | |
132 | |
133 class C(metaclass=abc.ABCMeta): | |
134 @classmethod | |
135 @abc.abstractmethod | |
136 def foo(cls): return cls.__name__ | |
137 self.assertRaises(TypeError, C) | |
138 class D(C): | |
139 @classmethod | |
140 def foo(cls): return super().foo() | |
141 self.assertEqual(D.foo(), 'D') | |
142 self.assertEqual(D().foo(), 'D') | |
143 | |
144 def test_abstractstaticmethod_basics(self): | |
145 @staticmethod | |
146 @abc.abstractmethod | |
147 def foo(): pass | |
148 self.assertTrue(foo.__isabstractmethod__) | |
149 @staticmethod | |
150 def bar(): pass | |
151 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) | |
152 | |
153 class C(metaclass=abc.ABCMeta): | |
154 @staticmethod | |
155 @abc.abstractmethod | |
156 def foo(): return 3 | |
157 self.assertRaises(TypeError, C) | |
158 class D(C): | |
159 @staticmethod | |
160 def foo(): return 4 | |
161 self.assertEqual(D.foo(), 4) | |
162 self.assertEqual(D().foo(), 4) | |
163 | |
164 def test_abstractmethod_integration(self): | |
165 for abstractthing in [abc.abstractmethod, abc.abstractproperty, | |
166 abc.abstractclassmethod, | |
167 abc.abstractstaticmethod]: | |
168 class C(metaclass=abc.ABCMeta): | |
169 @abstractthing | |
170 def foo(self): pass # abstract | |
171 def bar(self): pass # concrete | |
172 self.assertEqual(C.__abstractmethods__, {"foo"}) | |
173 self.assertRaises(TypeError, C) # because foo is abstract | |
174 self.assertTrue(isabstract(C)) | |
175 class D(C): | |
176 def bar(self): pass # concrete override of concrete | |
177 self.assertEqual(D.__abstractmethods__, {"foo"}) | |
178 self.assertRaises(TypeError, D) # because foo is still abstract | |
179 self.assertTrue(isabstract(D)) | |
180 class E(D): | |
181 def foo(self): pass | |
182 self.assertEqual(E.__abstractmethods__, set()) | |
183 E() # now foo is concrete, too | |
184 self.assertFalse(isabstract(E)) | |
185 class F(E): | |
186 @abstractthing | |
187 def bar(self): pass # abstract override of concrete | |
188 self.assertEqual(F.__abstractmethods__, {"bar"}) | |
189 self.assertRaises(TypeError, F) # because bar is abstract now | |
190 self.assertTrue(isabstract(F)) | |
191 | |
192 def test_descriptors_with_abstractmethod(self): | 177 def test_descriptors_with_abstractmethod(self): |
193 class C(metaclass=abc.ABCMeta): | 178 class C(metaclass=abc.ABCMeta): |
194 @property | 179 @property |
195 @abc.abstractmethod | 180 @abc.abstractmethod |
196 def foo(self): return 3 | 181 def foo(self): return 3 |
197 @foo.setter | 182 @foo.setter |
198 @abc.abstractmethod | 183 @abc.abstractmethod |
199 def foo(self, val): pass | 184 def foo(self, val): pass |
200 self.assertRaises(TypeError, C) | 185 self.assertRaises(TypeError, C) |
201 class D(C): | 186 class D(C): |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 self.assertIs(C, A.register(C)) | 294 self.assertIs(C, A.register(C)) |
310 | 295 |
311 def test_isinstance_invalidation(self): | 296 def test_isinstance_invalidation(self): |
312 class A(metaclass=abc.ABCMeta): | 297 class A(metaclass=abc.ABCMeta): |
313 pass | 298 pass |
314 class B: | 299 class B: |
315 pass | 300 pass |
316 b = B() | 301 b = B() |
317 self.assertNotIsInstance(b, A) | 302 self.assertNotIsInstance(b, A) |
318 self.assertNotIsInstance(b, (A,)) | 303 self.assertNotIsInstance(b, (A,)) |
| 304 token_old = abc.get_cache_token() |
319 A.register(B) | 305 A.register(B) |
| 306 token_new = abc.get_cache_token() |
| 307 self.assertNotEqual(token_old, token_new) |
320 self.assertIsInstance(b, A) | 308 self.assertIsInstance(b, A) |
321 self.assertIsInstance(b, (A,)) | 309 self.assertIsInstance(b, (A,)) |
322 | 310 |
323 def test_registration_builtins(self): | 311 def test_registration_builtins(self): |
324 class A(metaclass=abc.ABCMeta): | 312 class A(metaclass=abc.ABCMeta): |
325 pass | 313 pass |
326 A.register(int) | 314 A.register(int) |
327 self.assertIsInstance(42, A) | 315 self.assertIsInstance(42, A) |
328 self.assertIsInstance(42, (A,)) | 316 self.assertIsInstance(42, (A,)) |
329 self.assertTrue(issubclass(int, A)) | 317 self.assertTrue(issubclass(int, A)) |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 def __new__(cls): | 397 def __new__(cls): |
410 B.counter += 1 | 398 B.counter += 1 |
411 return super().__new__(cls) | 399 return super().__new__(cls) |
412 class C(A, B): | 400 class C(A, B): |
413 pass | 401 pass |
414 self.assertEqual(B.counter, 0) | 402 self.assertEqual(B.counter, 0) |
415 C() | 403 C() |
416 self.assertEqual(B.counter, 1) | 404 self.assertEqual(B.counter, 1) |
417 | 405 |
418 | 406 |
419 def test_main(): | |
420 support.run_unittest(TestABC) | |
421 | |
422 | |
423 if __name__ == "__main__": | 407 if __name__ == "__main__": |
424 unittest.main() | 408 unittest.main() |
LEFT | RIGHT |