blob: f43123fa24e659167f4c79ec5b482ad3ecbff283 [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
63 def test_registration_basics(self):
64 class A(metaclass=abc.ABCMeta):
65 pass
Christian Heimes043d6f62008-01-07 17:19:16 +000066 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000067 pass
68 b = B()
Benjamin Peterson14c61232010-08-17 01:14:01 +000069 self.assertFalse(issubclass(B, A))
70 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000071 self.assertEqual(isinstance(b, A), False)
Antoine Pitrouec569b72008-08-26 22:40:48 +000072 self.assertEqual(isinstance(b, (A,)), False)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000073 A.register(B)
Benjamin Peterson14c61232010-08-17 01:14:01 +000074 self.assertTrue(issubclass(B, A))
75 self.assertTrue(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000076 self.assertEqual(isinstance(b, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +000077 self.assertEqual(isinstance(b, (A,)), True)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000078 class C(B):
79 pass
80 c = C()
Benjamin Peterson14c61232010-08-17 01:14:01 +000081 self.assertTrue(issubclass(C, A))
82 self.assertTrue(issubclass(C, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +000083 self.assertEqual(isinstance(c, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +000084 self.assertEqual(isinstance(c, (A,)), True)
Guido van Rossumcd16bf62007-06-13 18:07:49 +000085
Christian Heimes68f5fbe2008-02-14 08:27:37 +000086 def test_isinstance_invalidation(self):
87 class A(metaclass=abc.ABCMeta):
88 pass
89 class B:
90 pass
91 b = B()
Benjamin Peterson14c61232010-08-17 01:14:01 +000092 self.assertFalse(isinstance(b, A))
93 self.assertFalse(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +000094 A.register(B)
Benjamin Peterson14c61232010-08-17 01:14:01 +000095 self.assertTrue(isinstance(b, A))
96 self.assertTrue(isinstance(b, (A,)))
Christian Heimes68f5fbe2008-02-14 08:27:37 +000097
Guido van Rossumcd16bf62007-06-13 18:07:49 +000098 def test_registration_builtins(self):
99 class A(metaclass=abc.ABCMeta):
100 pass
101 A.register(int)
102 self.assertEqual(isinstance(42, A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +0000103 self.assertEqual(isinstance(42, (A,)), True)
Benjamin Peterson14c61232010-08-17 01:14:01 +0000104 self.assertTrue(issubclass(int, A))
105 self.assertTrue(issubclass(int, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000106 class B(A):
107 pass
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000108 B.register(str)
109 class C(str): pass
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000110 self.assertEqual(isinstance("", A), True)
Antoine Pitrouec569b72008-08-26 22:40:48 +0000111 self.assertEqual(isinstance("", (A,)), True)
Benjamin Peterson14c61232010-08-17 01:14:01 +0000112 self.assertTrue(issubclass(str, A))
113 self.assertTrue(issubclass(str, (A,)))
114 self.assertTrue(issubclass(C, A))
115 self.assertTrue(issubclass(C, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000116
117 def test_registration_edge_cases(self):
118 class A(metaclass=abc.ABCMeta):
119 pass
120 A.register(A) # should pass silently
121 class A1(A):
122 pass
123 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Christian Heimes043d6f62008-01-07 17:19:16 +0000124 class B(object):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000125 pass
126 A1.register(B) # ok
127 A1.register(B) # should pass silently
128 class C(A):
129 pass
130 A.register(C) # should pass silently
131 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
132 C.register(B) # ok
133
Benjamin Peterson69de1572010-01-27 02:28:22 +0000134 def test_register_non_class(self):
135 class A(metaclass=abc.ABCMeta):
136 pass
137 self.assertRaisesRegexp(TypeError, "Can only register classes",
138 A.register, 4)
139
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000140 def test_registration_transitiveness(self):
141 class A(metaclass=abc.ABCMeta):
142 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000143 self.assertTrue(issubclass(A, A))
144 self.assertTrue(issubclass(A, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000145 class B(metaclass=abc.ABCMeta):
146 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000147 self.assertFalse(issubclass(A, B))
148 self.assertFalse(issubclass(A, (B,)))
149 self.assertFalse(issubclass(B, A))
150 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000151 class C(metaclass=abc.ABCMeta):
152 pass
153 A.register(B)
154 class B1(B):
155 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000156 self.assertTrue(issubclass(B1, A))
157 self.assertTrue(issubclass(B1, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000158 class C1(C):
159 pass
160 B1.register(C1)
Georg Brandlab91fde2009-08-13 08:51:18 +0000161 self.assertFalse(issubclass(C, B))
162 self.assertFalse(issubclass(C, (B,)))
163 self.assertFalse(issubclass(C, B1))
164 self.assertFalse(issubclass(C, (B1,)))
165 self.assertTrue(issubclass(C1, A))
166 self.assertTrue(issubclass(C1, (A,)))
167 self.assertTrue(issubclass(C1, B))
168 self.assertTrue(issubclass(C1, (B,)))
169 self.assertTrue(issubclass(C1, B1))
170 self.assertTrue(issubclass(C1, (B1,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000171 C1.register(int)
172 class MyInt(int):
173 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000174 self.assertTrue(issubclass(MyInt, A))
175 self.assertTrue(issubclass(MyInt, (A,)))
176 self.assertTrue(isinstance(42, A))
177 self.assertTrue(isinstance(42, (A,)))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000178
Guido van Rossum894d35e2007-09-11 20:42:30 +0000179 def test_all_new_methods_are_called(self):
180 class A(metaclass=abc.ABCMeta):
181 pass
Christian Heimes043d6f62008-01-07 17:19:16 +0000182 class B(object):
Guido van Rossum894d35e2007-09-11 20:42:30 +0000183 counter = 0
184 def __new__(cls):
185 B.counter += 1
186 return super().__new__(cls)
187 class C(A, B):
188 pass
189 self.assertEqual(B.counter, 0)
190 C()
191 self.assertEqual(B.counter, 1)
192
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000193
194def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000195 support.run_unittest(TestABC)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000196
197
198if __name__ == "__main__":
199 unittest.main()