blob: 0fa40cb430499fc11ec59eaa4116e7294eb4b0de [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 Peterson14c61232010-08-17 01:14:01 +000018 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000019 def bar(self): pass
Benjamin Peterson14c61232010-08-17 01:14:01 +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 Peterson14c61232010-08-17 01:14:01 +000025 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossum70d2b892007-08-01 17:52:23 +000026 def bar(self): pass
Benjamin Peterson14c61232010-08-17 01:14:01 +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
37 def test_abstractmethod_integration(self):
38 for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
39 class C(metaclass=abc.ABCMeta):
40 @abstractthing
41 def foo(self): pass # abstract
42 def bar(self): pass # concrete
43 self.assertEqual(C.__abstractmethods__, {"foo"})
44 self.assertRaises(TypeError, C) # because foo is abstract
Georg Brandlab91fde2009-08-13 08:51:18 +000045 self.assertTrue(isabstract(C))
Guido van Rossum70d2b892007-08-01 17:52:23 +000046 class D(C):
47 def bar(self): pass # concrete override of concrete
48 self.assertEqual(D.__abstractmethods__, {"foo"})
49 self.assertRaises(TypeError, D) # because foo is still abstract
Georg Brandlab91fde2009-08-13 08:51:18 +000050 self.assertTrue(isabstract(D))
Guido van Rossum70d2b892007-08-01 17:52:23 +000051 class E(D):
52 def foo(self): pass
53 self.assertEqual(E.__abstractmethods__, set())
54 E() # now foo is concrete, too
Georg Brandlab91fde2009-08-13 08:51:18 +000055 self.assertFalse(isabstract(E))
Guido van Rossum70d2b892007-08-01 17:52:23 +000056 class F(E):
57 @abstractthing
58 def bar(self): pass # abstract override of concrete
59 self.assertEqual(F.__abstractmethods__, {"bar"})
60 self.assertRaises(TypeError, F) # because bar is abstract now
Georg Brandlab91fde2009-08-13 08:51:18 +000061 self.assertTrue(isabstract(F))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000062
Benjamin Peterson0ad44fa2010-10-02 18:04:55 +000063 def test_type_has_no_abstractmethods(self):
64 # type pretends not to have __abstractmethods__.
65 self.assertRaises(AttributeError, getattr, type, "__abstractmethods__")
66 class meta(type):
67 pass
68 self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__")
69
70 def test_metaclass_abc(self):
71 # Metaclasses can be ABCs, too.
72 class A(metaclass=abc.ABCMeta):
73 @abc.abstractmethod
74 def x(self):
75 pass
76 self.assertEqual(A.__abstractmethods__, {"x"})
77 class meta(type, A):
78 def x(self):
79 return 1
80 class C(metaclass=meta):
81 pass
82
Guido van Rossumcd16bf62007-06-13 18:07:49 +000083 def test_registration_basics(self):
84 class A(metaclass=abc.ABCMeta):
85 pass
Christian Heimes043d6f62008-01-07 17:19:16 +000086 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000087 pass
88 b = B()
Benjamin Peterson14c61232010-08-17 01:14:01 +000089 self.assertFalse(issubclass(B, A))
90 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000091 self.assertEqual(isinstance(b, A), False)
Antoine Pitrouec569b72008-08-26 22:40:48 +000092 self.assertEqual(isinstance(b, (A,)), False)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000093 A.register(B)
Benjamin Peterson14c61232010-08-17 01:14:01 +000094 self.assertTrue(issubclass(B, A))
95 self.assertTrue(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000096 self.assertEqual(isinstance(b, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +000097 self.assertEqual(isinstance(b, (A,)), True)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000098 class C(B):
99 pass
100 c = C()
Benjamin Peterson14c61232010-08-17 01:14:01 +0000101 self.assertTrue(issubclass(C, A))
102 self.assertTrue(issubclass(C, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000103 self.assertEqual(isinstance(c, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +0000104 self.assertEqual(isinstance(c, (A,)), True)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000105
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000106 def test_isinstance_invalidation(self):
107 class A(metaclass=abc.ABCMeta):
108 pass
109 class B:
110 pass
111 b = B()
Benjamin Peterson14c61232010-08-17 01:14:01 +0000112 self.assertFalse(isinstance(b, A))
113 self.assertFalse(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000114 A.register(B)
Benjamin Peterson14c61232010-08-17 01:14:01 +0000115 self.assertTrue(isinstance(b, A))
116 self.assertTrue(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000117
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000118 def test_registration_builtins(self):
119 class A(metaclass=abc.ABCMeta):
120 pass
121 A.register(int)
122 self.assertEqual(isinstance(42, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +0000123 self.assertEqual(isinstance(42, (A,)), True)
Benjamin Peterson14c61232010-08-17 01:14:01 +0000124 self.assertTrue(issubclass(int, A))
125 self.assertTrue(issubclass(int, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000126 class B(A):
127 pass
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000128 B.register(str)
129 class C(str): pass
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000130 self.assertEqual(isinstance("", A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +0000131 self.assertEqual(isinstance("", (A,)), True)
Benjamin Peterson14c61232010-08-17 01:14:01 +0000132 self.assertTrue(issubclass(str, A))
133 self.assertTrue(issubclass(str, (A,)))
134 self.assertTrue(issubclass(C, A))
135 self.assertTrue(issubclass(C, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000136
137 def test_registration_edge_cases(self):
138 class A(metaclass=abc.ABCMeta):
139 pass
140 A.register(A) # should pass silently
141 class A1(A):
142 pass
143 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Christian Heimes043d6f62008-01-07 17:19:16 +0000144 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000145 pass
146 A1.register(B) # ok
147 A1.register(B) # should pass silently
148 class C(A):
149 pass
150 A.register(C) # should pass silently
151 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
152 C.register(B) # ok
153
Benjamin Peterson69de1572010-01-27 02:28:22 +0000154 def test_register_non_class(self):
155 class A(metaclass=abc.ABCMeta):
156 pass
157 self.assertRaisesRegexp(TypeError, "Can only register classes",
158 A.register, 4)
159
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000160 def test_registration_transitiveness(self):
161 class A(metaclass=abc.ABCMeta):
162 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000163 self.assertTrue(issubclass(A, A))
164 self.assertTrue(issubclass(A, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000165 class B(metaclass=abc.ABCMeta):
166 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000167 self.assertFalse(issubclass(A, B))
168 self.assertFalse(issubclass(A, (B,)))
169 self.assertFalse(issubclass(B, A))
170 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000171 class C(metaclass=abc.ABCMeta):
172 pass
173 A.register(B)
174 class B1(B):
175 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000176 self.assertTrue(issubclass(B1, A))
177 self.assertTrue(issubclass(B1, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000178 class C1(C):
179 pass
180 B1.register(C1)
Georg Brandlab91fde2009-08-13 08:51:18 +0000181 self.assertFalse(issubclass(C, B))
182 self.assertFalse(issubclass(C, (B,)))
183 self.assertFalse(issubclass(C, B1))
184 self.assertFalse(issubclass(C, (B1,)))
185 self.assertTrue(issubclass(C1, A))
186 self.assertTrue(issubclass(C1, (A,)))
187 self.assertTrue(issubclass(C1, B))
188 self.assertTrue(issubclass(C1, (B,)))
189 self.assertTrue(issubclass(C1, B1))
190 self.assertTrue(issubclass(C1, (B1,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000191 C1.register(int)
192 class MyInt(int):
193 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000194 self.assertTrue(issubclass(MyInt, A))
195 self.assertTrue(issubclass(MyInt, (A,)))
196 self.assertTrue(isinstance(42, A))
197 self.assertTrue(isinstance(42, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000198
Guido van Rossum894d35e2007-09-11 20:42:30 +0000199 def test_all_new_methods_are_called(self):
200 class A(metaclass=abc.ABCMeta):
201 pass
Christian Heimes043d6f62008-01-07 17:19:16 +0000202 class B(object):
Guido van Rossum894d35e2007-09-11 20:42:30 +0000203 counter = 0
204 def __new__(cls):
205 B.counter += 1
206 return super().__new__(cls)
207 class C(A, B):
208 pass
209 self.assertEqual(B.counter, 0)
210 C()
211 self.assertEqual(B.counter, 1)
212
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000213
214def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000215 support.run_unittest(TestABC)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000216
217
218if __name__ == "__main__":
219 unittest.main()