blob: edd2c047f222196f4bb9e1afa398208338701a51 [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
Benjamin Peterson52c36052010-08-21 03:03:22 +00006import unittest, weakref
Guido van Rossumb5591132007-09-10 22:36:02 +00007from 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
Benjamin Petersona5d5cc42010-10-02 00:08:58 +000073 def test_type_has_no_abstractmethods(self):
74 # type pretends not to have __abstractmethods__.
75 self.assertRaises(AttributeError, getattr, type, "__abstractmethods__")
76 class meta(type):
77 pass
78 self.assertRaises(AttributeError, getattr, meta, "__abstractmethods__")
79
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +000080 def test_isinstance_class(self):
81 class A:
82 __metaclass__ = abc.ABCMeta
83 class OldstyleClass:
84 pass
85 self.assertFalse(isinstance(OldstyleClass, A))
86 self.assertTrue(isinstance(OldstyleClass, type(OldstyleClass)))
87 self.assertFalse(isinstance(A, OldstyleClass))
88 # This raises a recursion depth error, but is low-priority:
89 # self.assertTrue(isinstance(A, abc.ABCMeta))
90
Guido van Rossumb5591132007-09-10 22:36:02 +000091 def test_registration_basics(self):
92 class A:
93 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +000094 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +000095 pass
96 b = B()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +000097 self.assertFalse(issubclass(B, A))
98 self.assertFalse(issubclass(B, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +000099 self.assertNotIsInstance(b, A)
100 self.assertNotIsInstance(b, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000101 A.register(B)
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000102 self.assertTrue(issubclass(B, A))
103 self.assertTrue(issubclass(B, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000104 self.assertIsInstance(b, A)
105 self.assertIsInstance(b, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000106 class C(B):
107 pass
108 c = C()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000109 self.assertTrue(issubclass(C, A))
110 self.assertTrue(issubclass(C, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000111 self.assertIsInstance(c, A)
112 self.assertIsInstance(c, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000113
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000114 def test_isinstance_invalidation(self):
115 class A:
116 __metaclass__ = abc.ABCMeta
117 class B(object):
118 pass
119 b = B()
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000120 self.assertFalse(isinstance(b, A))
121 self.assertFalse(isinstance(b, (A,)))
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000122 A.register(B)
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000123 self.assertTrue(isinstance(b, A))
124 self.assertTrue(isinstance(b, (A,)))
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000125
Guido van Rossumb5591132007-09-10 22:36:02 +0000126 def test_registration_builtins(self):
127 class A:
128 __metaclass__ = abc.ABCMeta
129 A.register(int)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000130 self.assertIsInstance(42, A)
131 self.assertIsInstance(42, (A,))
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000132 self.assertTrue(issubclass(int, A))
133 self.assertTrue(issubclass(int, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000134 class B(A):
135 pass
136 B.register(basestring)
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000137 self.assertIsInstance("", A)
138 self.assertIsInstance("", (A,))
Benjamin Peterson5d6026a2010-08-17 01:10:45 +0000139 self.assertTrue(issubclass(str, A))
140 self.assertTrue(issubclass(str, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000141
142 def test_registration_edge_cases(self):
143 class A:
144 __metaclass__ = abc.ABCMeta
145 A.register(A) # should pass silently
146 class A1(A):
147 pass
148 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000149 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +0000150 pass
151 A1.register(B) # ok
152 A1.register(B) # should pass silently
153 class C(A):
154 pass
155 A.register(C) # should pass silently
156 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
157 C.register(B) # ok
158
Benjamin Peterson2deb5c72010-01-27 02:16:42 +0000159 def test_register_non_class(self):
160 class A(object):
161 __metaclass__ = abc.ABCMeta
162 self.assertRaisesRegexp(TypeError, "Can only register classes",
163 A.register, 4)
164
Guido van Rossumb5591132007-09-10 22:36:02 +0000165 def test_registration_transitiveness(self):
166 class A:
167 __metaclass__ = abc.ABCMeta
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000168 self.assertTrue(issubclass(A, A))
169 self.assertTrue(issubclass(A, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000170 class B:
171 __metaclass__ = abc.ABCMeta
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000172 self.assertFalse(issubclass(A, B))
173 self.assertFalse(issubclass(A, (B,)))
174 self.assertFalse(issubclass(B, A))
175 self.assertFalse(issubclass(B, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000176 class C:
177 __metaclass__ = abc.ABCMeta
178 A.register(B)
179 class B1(B):
180 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000181 self.assertTrue(issubclass(B1, A))
182 self.assertTrue(issubclass(B1, (A,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000183 class C1(C):
184 pass
185 B1.register(C1)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000186 self.assertFalse(issubclass(C, B))
187 self.assertFalse(issubclass(C, (B,)))
188 self.assertFalse(issubclass(C, B1))
189 self.assertFalse(issubclass(C, (B1,)))
190 self.assertTrue(issubclass(C1, A))
191 self.assertTrue(issubclass(C1, (A,)))
192 self.assertTrue(issubclass(C1, B))
193 self.assertTrue(issubclass(C1, (B,)))
194 self.assertTrue(issubclass(C1, B1))
195 self.assertTrue(issubclass(C1, (B1,)))
Guido van Rossumb5591132007-09-10 22:36:02 +0000196 C1.register(int)
197 class MyInt(int):
198 pass
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000199 self.assertTrue(issubclass(MyInt, A))
200 self.assertTrue(issubclass(MyInt, (A,)))
Ezio Melottib0f5adc2010-01-24 16:58:36 +0000201 self.assertIsInstance(42, A)
202 self.assertIsInstance(42, (A,))
Guido van Rossumb5591132007-09-10 22:36:02 +0000203
Guido van Rossum64c06e32007-11-22 00:55:51 +0000204 def test_all_new_methods_are_called(self):
205 class A:
206 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000207 class B(object):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000208 counter = 0
209 def __new__(cls):
210 B.counter += 1
211 return super(B, cls).__new__(cls)
212 class C(A, B):
213 pass
214 self.assertEqual(B.counter, 0)
215 C()
216 self.assertEqual(B.counter, 1)
217
Benjamin Peterson52c36052010-08-21 03:03:22 +0000218 def test_cache_leak(self):
219 # See issue #2521.
220 class A(object):
221 __metaclass__ = abc.ABCMeta
222 @abc.abstractmethod
223 def f(self):
224 pass
225 class C(A):
226 def f(self):
227 A.f(self)
228 r = weakref.ref(C)
229 # Trigger cache.
230 C().f()
231 del C
232 test_support.gc_collect()
233 self.assertEqual(r(), None)
Guido van Rossumb5591132007-09-10 22:36:02 +0000234
235def test_main():
236 test_support.run_unittest(TestABC)
237
238
239if __name__ == "__main__":
240 unittest.main()