blob: b5af46b522ff317b5682d4683be6f7b559801c6d [file] [log] [blame]
Guido van Rossumb5591132007-09-10 22:36:02 +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 Rossumb5591132007-09-10 22:36:02 +00006import unittest
7from test import test_support
8
9import abc
Christian Heimes608c1d82008-03-03 18:28:04 +000010from inspect import isabstract
Guido van Rossumb5591132007-09-10 22:36:02 +000011
12
13class TestABC(unittest.TestCase):
14
15 def test_abstractmethod_basics(self):
16 @abc.abstractmethod
17 def foo(self): pass
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000018 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossumb5591132007-09-10 22:36:02 +000019 def bar(self): pass
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000020 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Guido van Rossumb5591132007-09-10 22:36:02 +000021
22 def test_abstractproperty_basics(self):
23 @abc.abstractproperty
24 def foo(self): pass
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000025 self.assertTrue(foo.__isabstractmethod__)
Guido van Rossumb5591132007-09-10 22:36:02 +000026 def bar(self): pass
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000027 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Guido van Rossumb5591132007-09-10 22:36:02 +000028
29 class C:
30 __metaclass__ = abc.ABCMeta
31 @abc.abstractproperty
32 def foo(self): return 3
33 class D(C):
34 @property
35 def foo(self): return super(D, self).foo
36 self.assertEqual(D().foo, 3)
37
38 def test_abstractmethod_integration(self):
39 for abstractthing in [abc.abstractmethod, abc.abstractproperty]:
40 class C:
41 __metaclass__ = abc.ABCMeta
42 @abstractthing
43 def foo(self): pass # abstract
44 def bar(self): pass # concrete
45 self.assertEqual(C.__abstractmethods__, set(["foo"]))
46 self.assertRaises(TypeError, C) # because foo is abstract
Benjamin Peterson5c8da862009-06-30 22:57:08 +000047 self.assertTrue(isabstract(C))
Guido van Rossumb5591132007-09-10 22:36:02 +000048 class D(C):
49 def bar(self): pass # concrete override of concrete
50 self.assertEqual(D.__abstractmethods__, set(["foo"]))
51 self.assertRaises(TypeError, D) # because foo is still abstract
Benjamin Peterson5c8da862009-06-30 22:57:08 +000052 self.assertTrue(isabstract(D))
Guido van Rossumb5591132007-09-10 22:36:02 +000053 class E(D):
54 def foo(self): pass
55 self.assertEqual(E.__abstractmethods__, set())
56 E() # now foo is concrete, too
Benjamin Peterson5c8da862009-06-30 22:57:08 +000057 self.assertFalse(isabstract(E))
Guido van Rossumb5591132007-09-10 22:36:02 +000058 class F(E):
59 @abstractthing
60 def bar(self): pass # abstract override of concrete
61 self.assertEqual(F.__abstractmethods__, set(["bar"]))
62 self.assertRaises(TypeError, F) # because bar is abstract now
Benjamin Peterson5c8da862009-06-30 22:57:08 +000063 self.assertTrue(isabstract(F))
Guido van Rossumb5591132007-09-10 22:36:02 +000064
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +000065 def test_subclass_oldstyle_class(self):
66 class A:
67 __metaclass__ = abc.ABCMeta
68 class OldstyleClass:
69 pass
70 self.assertFalse(issubclass(OldstyleClass, A))
71 self.assertFalse(issubclass(A, OldstyleClass))
72
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +000073 def test_isinstance_class(self):
74 class A:
75 __metaclass__ = abc.ABCMeta
76 class OldstyleClass:
77 pass
78 self.assertFalse(isinstance(OldstyleClass, A))
79 self.assertTrue(isinstance(OldstyleClass, type(OldstyleClass)))
80 self.assertFalse(isinstance(A, OldstyleClass))
81 # This raises a recursion depth error, but is low-priority:
82 # self.assertTrue(isinstance(A, abc.ABCMeta))
83
Guido van Rossumb5591132007-09-10 22:36:02 +000084 def test_registration_basics(self):
85 class A:
86 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +000087 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +000088 pass
89 b = B()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000090 self.assertFalse(issubclass(B, A))
91 self.assertFalse(issubclass(B, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +000092 self.assertNotIsInstance(b, A)
93 self.assertNotIsInstance(b, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +000094 A.register(B)
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000095 self.assertTrue(issubclass(B, A))
96 self.assertTrue(issubclass(B, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +000097 self.assertIsInstance(b, A)
98 self.assertIsInstance(b, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +000099 class C(B):
100 pass
101 c = C()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000102 self.assertTrue(issubclass(C, A))
103 self.assertTrue(issubclass(C, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000104 self.assertIsInstance(c, A)
105 self.assertIsInstance(c, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000106
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000107 def test_isinstance_invalidation(self):
108 class A:
109 __metaclass__ = abc.ABCMeta
110 class B(object):
111 pass
112 b = B()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000113 self.assertFalse(isinstance(b, A))
114 self.assertFalse(isinstance(b, (A,)))
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000115 A.register(B)
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000116 self.assertTrue(isinstance(b, A))
117 self.assertTrue(isinstance(b, (A,)))
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000118
Guido van Rossumb5591132007-09-10 22:36:02 +0000119 def test_registration_builtins(self):
120 class A:
121 __metaclass__ = abc.ABCMeta
122 A.register(int)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000123 self.assertIsInstance(42, A)
124 self.assertIsInstance(42, (A,))
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000125 self.assertTrue(issubclass(int, A))
126 self.assertTrue(issubclass(int, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000127 class B(A):
128 pass
129 B.register(basestring)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000130 self.assertIsInstance("", A)
131 self.assertIsInstance("", (A,))
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000132 self.assertTrue(issubclass(str, A))
133 self.assertTrue(issubclass(str, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000134
135 def test_registration_edge_cases(self):
136 class A:
137 __metaclass__ = abc.ABCMeta
138 A.register(A) # should pass silently
139 class A1(A):
140 pass
141 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000142 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +0000143 pass
144 A1.register(B) # ok
145 A1.register(B) # should pass silently
146 class C(A):
147 pass
148 A.register(C) # should pass silently
149 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
150 C.register(B) # ok
151
Benjamin Peterson2deb5c72010-01-27 02:16:42 +0000152 def test_register_non_class(self):
153 class A(object):
154 __metaclass__ = abc.ABCMeta
155 self.assertRaisesRegexp(TypeError, "Can only register classes",
156 A.register, 4)
157
Guido van Rossumb5591132007-09-10 22:36:02 +0000158 def test_registration_transitiveness(self):
159 class A:
160 __metaclass__ = abc.ABCMeta
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000161 self.assertTrue(issubclass(A, A))
162 self.assertTrue(issubclass(A, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000163 class B:
164 __metaclass__ = abc.ABCMeta
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000165 self.assertFalse(issubclass(A, B))
166 self.assertFalse(issubclass(A, (B,)))
167 self.assertFalse(issubclass(B, A))
168 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000169 class C:
170 __metaclass__ = abc.ABCMeta
171 A.register(B)
172 class B1(B):
173 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000174 self.assertTrue(issubclass(B1, A))
175 self.assertTrue(issubclass(B1, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000176 class C1(C):
177 pass
178 B1.register(C1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000179 self.assertFalse(issubclass(C, B))
180 self.assertFalse(issubclass(C, (B,)))
181 self.assertFalse(issubclass(C, B1))
182 self.assertFalse(issubclass(C, (B1,)))
183 self.assertTrue(issubclass(C1, A))
184 self.assertTrue(issubclass(C1, (A,)))
185 self.assertTrue(issubclass(C1, B))
186 self.assertTrue(issubclass(C1, (B,)))
187 self.assertTrue(issubclass(C1, B1))
188 self.assertTrue(issubclass(C1, (B1,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000189 C1.register(int)
190 class MyInt(int):
191 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000192 self.assertTrue(issubclass(MyInt, A))
193 self.assertTrue(issubclass(MyInt, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000194 self.assertIsInstance(42, A)
195 self.assertIsInstance(42, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000196
Guido van Rossum64c06e32007-11-22 00:55:51 +0000197 def test_all_new_methods_are_called(self):
198 class A:
199 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000200 class B(object):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000201 counter = 0
202 def __new__(cls):
203 B.counter += 1
204 return super(B, cls).__new__(cls)
205 class C(A, B):
206 pass
207 self.assertEqual(B.counter, 0)
208 C()
209 self.assertEqual(B.counter, 1)
210
Guido van Rossumb5591132007-09-10 22:36:02 +0000211
212def test_main():
213 test_support.run_unittest(TestABC)
214
215
216if __name__ == "__main__":
217 unittest.main()