move sections
[python/dscho.git] / Lib / test / test_abc.py
blob31f1986ae2474fad755728529f541a5a3f062302
1 # Copyright 2007 Google, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement.
4 """Unit tests for abc.py."""
6 import unittest
7 from test import test_support
9 import abc
10 from inspect import isabstract
13 class TestABC(unittest.TestCase):
15 def test_abstractmethod_basics(self):
16 @abc.abstractmethod
17 def foo(self): pass
18 self.assertEqual(foo.__isabstractmethod__, True)
19 def bar(self): pass
20 self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
22 def test_abstractproperty_basics(self):
23 @abc.abstractproperty
24 def foo(self): pass
25 self.assertEqual(foo.__isabstractmethod__, True)
26 def bar(self): pass
27 self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
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)
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
47 self.assertTrue(isabstract(C))
48 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
52 self.assertTrue(isabstract(D))
53 class E(D):
54 def foo(self): pass
55 self.assertEqual(E.__abstractmethods__, set())
56 E() # now foo is concrete, too
57 self.assertFalse(isabstract(E))
58 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
63 self.assertTrue(isabstract(F))
65 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))
73 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))
84 def test_registration_basics(self):
85 class A:
86 __metaclass__ = abc.ABCMeta
87 class B(object):
88 pass
89 b = B()
90 self.assertEqual(issubclass(B, A), False)
91 self.assertEqual(issubclass(B, (A,)), False)
92 self.assertNotIsInstance(b, A)
93 self.assertNotIsInstance(b, (A,))
94 A.register(B)
95 self.assertEqual(issubclass(B, A), True)
96 self.assertEqual(issubclass(B, (A,)), True)
97 self.assertIsInstance(b, A)
98 self.assertIsInstance(b, (A,))
99 class C(B):
100 pass
101 c = C()
102 self.assertEqual(issubclass(C, A), True)
103 self.assertEqual(issubclass(C, (A,)), True)
104 self.assertIsInstance(c, A)
105 self.assertIsInstance(c, (A,))
107 def test_isinstance_invalidation(self):
108 class A:
109 __metaclass__ = abc.ABCMeta
110 class B(object):
111 pass
112 b = B()
113 self.assertEqual(isinstance(b, A), False)
114 self.assertEqual(isinstance(b, (A,)), False)
115 A.register(B)
116 self.assertEqual(isinstance(b, A), True)
117 self.assertEqual(isinstance(b, (A,)), True)
119 def test_registration_builtins(self):
120 class A:
121 __metaclass__ = abc.ABCMeta
122 A.register(int)
123 self.assertIsInstance(42, A)
124 self.assertIsInstance(42, (A,))
125 self.assertEqual(issubclass(int, A), True)
126 self.assertEqual(issubclass(int, (A,)), True)
127 class B(A):
128 pass
129 B.register(basestring)
130 self.assertIsInstance("", A)
131 self.assertIsInstance("", (A,))
132 self.assertEqual(issubclass(str, A), True)
133 self.assertEqual(issubclass(str, (A,)), True)
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
142 class B(object):
143 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
152 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)
158 def test_registration_transitiveness(self):
159 class A:
160 __metaclass__ = abc.ABCMeta
161 self.assertTrue(issubclass(A, A))
162 self.assertTrue(issubclass(A, (A,)))
163 class B:
164 __metaclass__ = abc.ABCMeta
165 self.assertFalse(issubclass(A, B))
166 self.assertFalse(issubclass(A, (B,)))
167 self.assertFalse(issubclass(B, A))
168 self.assertFalse(issubclass(B, (A,)))
169 class C:
170 __metaclass__ = abc.ABCMeta
171 A.register(B)
172 class B1(B):
173 pass
174 self.assertTrue(issubclass(B1, A))
175 self.assertTrue(issubclass(B1, (A,)))
176 class C1(C):
177 pass
178 B1.register(C1)
179 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,)))
189 C1.register(int)
190 class MyInt(int):
191 pass
192 self.assertTrue(issubclass(MyInt, A))
193 self.assertTrue(issubclass(MyInt, (A,)))
194 self.assertIsInstance(42, A)
195 self.assertIsInstance(42, (A,))
197 def test_all_new_methods_are_called(self):
198 class A:
199 __metaclass__ = abc.ABCMeta
200 class B(object):
201 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)
209 self.assertEqual(B.counter, 1)
212 def test_main():
213 test_support.run_unittest(TestABC)
216 if __name__ == "__main__":
217 unittest.main()