blob: d8961e73ab3af42da70c241e01e8474bb278e5bd [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Unit tests for abc.py."""
5
Guido van Rossumcd16bf62007-06-13 18:07:49 +00006import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Guido van Rossumcd16bf62007-06-13 18:07:49 +00008
9import abc
Christian Heimesbe5b30b2008-03-03 19:18:51 +000010from inspect import isabstract
Guido van Rossumcd16bf62007-06-13 18:07:49 +000011
12
13class TestABC(unittest.TestCase):
14
15 def test_abstractmethod_basics(self):
16 @abc.abstractmethod
17 def foo(self): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000018 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000019 def bar(self): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000020 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000021
Guido van Rossum70d2b892007-08-01 17:52:23 +000022 def test_abstractproperty_basics(self):
23 @abc.abstractproperty
24 def foo(self): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000025 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossum70d2b892007-08-01 17:52:23 +000026 def bar(self): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000027 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Guido van Rossum70d2b892007-08-01 17:52:23 +000028
Guido van Rossumcd16bf62007-06-13 18:07:49 +000029 class C(metaclass=abc.ABCMeta):
Guido van Rossum70d2b892007-08-01 17:52:23 +000030 @abc.abstractproperty
31 def foo(self): return 3
Guido van Rossumcd16bf62007-06-13 18:07:49 +000032 class D(C):
Guido van Rossum70d2b892007-08-01 17:52:23 +000033 @property
34 def foo(self): return super().foo
35 self.assertEqual(D().foo, 3)
36
Benjamin Peterson45c257f2010-08-17 00:52:52 +000037 def test_abstractclassmethod_basics(self):
38 @abc.abstractclassmethod
39 def foo(cls): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000040 self.assertTrue(foo.__isabstractmethod__)
Benjamin Peterson45c257f2010-08-17 00:52:52 +000041 @classmethod
42 def bar(cls): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000043 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Benjamin Peterson45c257f2010-08-17 00:52:52 +000044
45 class C(metaclass=abc.ABCMeta):
46 @abc.abstractclassmethod
47 def foo(cls): return cls.__name__
48 self.assertRaises(TypeError, C)
49 class D(C):
50 @classmethod
51 def foo(cls): return super().foo()
52 self.assertEqual(D.foo(), 'D')
53 self.assertEqual(D().foo(), 'D')
54
55 def test_abstractstaticmethod_basics(self):
56 @abc.abstractstaticmethod
57 def foo(): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000058 self.assertTrue(foo.__isabstractmethod__)
Benjamin Peterson45c257f2010-08-17 00:52:52 +000059 @staticmethod
60 def bar(): pass
Benjamin Peterson83cd3b92010-08-17 01:07:53 +000061 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Benjamin Peterson45c257f2010-08-17 00:52:52 +000062
63 class C(metaclass=abc.ABCMeta):
64 @abc.abstractstaticmethod
65 def foo(): return 3
66 self.assertRaises(TypeError, C)
67 class D(C):
68 @staticmethod
69 def foo(): return 4
70 self.assertEqual(D.foo(), 4)
71 self.assertEqual(D().foo(), 4)
72
Guido van Rossum70d2b892007-08-01 17:52:23 +000073 def test_abstractmethod_integration(self):
Benjamin Peterson45c257f2010-08-17 00:52:52 +000074 for abstractthing in [abc.abstractmethod, abc.abstractproperty,
75 abc.abstractclassmethod,
76 abc.abstractstaticmethod]:
Guido van Rossum70d2b892007-08-01 17:52:23 +000077 class C(metaclass=abc.ABCMeta):
78 @abstractthing
79 def foo(self): pass # abstract
80 def bar(self): pass # concrete
81 self.assertEqual(C.__abstractmethods__, {"foo"})
82 self.assertRaises(TypeError, C) # because foo is abstract
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000083 self.assertTrue(isabstract(C))
Guido van Rossum70d2b892007-08-01 17:52:23 +000084 class D(C):
85 def bar(self): pass # concrete override of concrete
86 self.assertEqual(D.__abstractmethods__, {"foo"})
87 self.assertRaises(TypeError, D) # because foo is still abstract
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000088 self.assertTrue(isabstract(D))
Guido van Rossum70d2b892007-08-01 17:52:23 +000089 class E(D):
90 def foo(self): pass
91 self.assertEqual(E.__abstractmethods__, set())
92 E() # now foo is concrete, too
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000093 self.assertFalse(isabstract(E))
Guido van Rossum70d2b892007-08-01 17:52:23 +000094 class F(E):
95 @abstractthing
96 def bar(self): pass # abstract override of concrete
97 self.assertEqual(F.__abstractmethods__, {"bar"})
98 self.assertRaises(TypeError, F) # because bar is abstract now
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000099 self.assertTrue(isabstract(F))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000100
Christian Heimes043d6f62008-01-07 17:19:16 +0000101 def test_subclass_oldstyle_class(self):
102 class A:
103 __metaclass__ = abc.ABCMeta
104 class OldstyleClass:
105 pass
106 self.assertFalse(issubclass(OldstyleClass, A))
107 self.assertFalse(issubclass(A, OldstyleClass))
108
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000109 def test_registration_basics(self):
110 class A(metaclass=abc.ABCMeta):
111 pass
Christian Heimes043d6f62008-01-07 17:19:16 +0000112 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000113 pass
114 b = B()
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000115 self.assertFalse(issubclass(B, A))
116 self.assertFalse(issubclass(B, (A,)))
Ezio Melottie9615932010-01-24 19:26:24 +0000117 self.assertNotIsInstance(b, A)
118 self.assertNotIsInstance(b, (A,))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000119 A.register(B)
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000120 self.assertTrue(issubclass(B, A))
121 self.assertTrue(issubclass(B, (A,)))
Ezio Melottie9615932010-01-24 19:26:24 +0000122 self.assertIsInstance(b, A)
123 self.assertIsInstance(b, (A,))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000124 class C(B):
125 pass
126 c = C()
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000127 self.assertTrue(issubclass(C, A))
128 self.assertTrue(issubclass(C, (A,)))
Ezio Melottie9615932010-01-24 19:26:24 +0000129 self.assertIsInstance(c, A)
130 self.assertIsInstance(c, (A,))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000131
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000132 def test_isinstance_invalidation(self):
133 class A(metaclass=abc.ABCMeta):
134 pass
135 class B:
136 pass
137 b = B()
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000138 self.assertFalse(isinstance(b, A))
139 self.assertFalse(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000140 A.register(B)
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000141 self.assertTrue(isinstance(b, A))
142 self.assertTrue(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000143
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000144 def test_registration_builtins(self):
145 class A(metaclass=abc.ABCMeta):
146 pass
147 A.register(int)
Ezio Melottie9615932010-01-24 19:26:24 +0000148 self.assertIsInstance(42, A)
149 self.assertIsInstance(42, (A,))
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000150 self.assertTrue(issubclass(int, A))
151 self.assertTrue(issubclass(int, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000152 class B(A):
153 pass
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000154 B.register(str)
155 class C(str): pass
Ezio Melottie9615932010-01-24 19:26:24 +0000156 self.assertIsInstance("", A)
157 self.assertIsInstance("", (A,))
Benjamin Peterson83cd3b92010-08-17 01:07:53 +0000158 self.assertTrue(issubclass(str, A))
159 self.assertTrue(issubclass(str, (A,)))
160 self.assertTrue(issubclass(C, A))
161 self.assertTrue(issubclass(C, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000162
163 def test_registration_edge_cases(self):
164 class A(metaclass=abc.ABCMeta):
165 pass
166 A.register(A) # should pass silently
167 class A1(A):
168 pass
169 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Christian Heimes043d6f62008-01-07 17:19:16 +0000170 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000171 pass
172 A1.register(B) # ok
173 A1.register(B) # should pass silently
174 class C(A):
175 pass
176 A.register(C) # should pass silently
177 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
178 C.register(B) # ok
179
Benjamin Petersond6326642010-01-27 02:25:58 +0000180 def test_register_non_class(self):
181 class A(metaclass=abc.ABCMeta):
182 pass
183 self.assertRaisesRegexp(TypeError, "Can only register classes",
184 A.register, 4)
185
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000186 def test_registration_transitiveness(self):
187 class A(metaclass=abc.ABCMeta):
188 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000189 self.assertTrue(issubclass(A, A))
190 self.assertTrue(issubclass(A, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000191 class B(metaclass=abc.ABCMeta):
192 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000193 self.assertFalse(issubclass(A, B))
194 self.assertFalse(issubclass(A, (B,)))
195 self.assertFalse(issubclass(B, A))
196 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000197 class C(metaclass=abc.ABCMeta):
198 pass
199 A.register(B)
200 class B1(B):
201 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000202 self.assertTrue(issubclass(B1, A))
203 self.assertTrue(issubclass(B1, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000204 class C1(C):
205 pass
206 B1.register(C1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000207 self.assertFalse(issubclass(C, B))
208 self.assertFalse(issubclass(C, (B,)))
209 self.assertFalse(issubclass(C, B1))
210 self.assertFalse(issubclass(C, (B1,)))
211 self.assertTrue(issubclass(C1, A))
212 self.assertTrue(issubclass(C1, (A,)))
213 self.assertTrue(issubclass(C1, B))
214 self.assertTrue(issubclass(C1, (B,)))
215 self.assertTrue(issubclass(C1, B1))
216 self.assertTrue(issubclass(C1, (B1,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000217 C1.register(int)
218 class MyInt(int):
219 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000220 self.assertTrue(issubclass(MyInt, A))
221 self.assertTrue(issubclass(MyInt, (A,)))
Ezio Melottie9615932010-01-24 19:26:24 +0000222 self.assertIsInstance(42, A)
223 self.assertIsInstance(42, (A,))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000224
Guido van Rossum894d35e2007-09-11 20:42:30 +0000225 def test_all_new_methods_are_called(self):
226 class A(metaclass=abc.ABCMeta):
227 pass
Christian Heimes043d6f62008-01-07 17:19:16 +0000228 class B(object):
Guido van Rossum894d35e2007-09-11 20:42:30 +0000229 counter = 0
230 def __new__(cls):
231 B.counter += 1
232 return super().__new__(cls)
233 class C(A, B):
234 pass
235 self.assertEqual(B.counter, 0)
236 C()
237 self.assertEqual(B.counter, 1)
238
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000239
240def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000241 support.run_unittest(TestABC)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000242
243
244if __name__ == "__main__":
245 unittest.main()