blob: ac5f7ee245a272f8cb8e9ea11e03b35b1a0fa1bf [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
6import sys
7import unittest
8from test import test_support
9
10import abc
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
18 self.assertEqual(foo.__isabstractmethod__, True)
19 def bar(self): pass
20 self.assertEqual(hasattr(bar, "__isabstractmethod__"), False)
21
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)
28
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
47 class D(C):
48 def bar(self): pass # concrete override of concrete
49 self.assertEqual(D.__abstractmethods__, set(["foo"]))
50 self.assertRaises(TypeError, D) # because foo is still abstract
51 class E(D):
52 def foo(self): pass
53 self.assertEqual(E.__abstractmethods__, set())
54 E() # now foo is concrete, too
55 class F(E):
56 @abstractthing
57 def bar(self): pass # abstract override of concrete
58 self.assertEqual(F.__abstractmethods__, set(["bar"]))
59 self.assertRaises(TypeError, F) # because bar is abstract now
60
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +000061 def test_subclass_oldstyle_class(self):
62 class A:
63 __metaclass__ = abc.ABCMeta
64 class OldstyleClass:
65 pass
66 self.assertFalse(issubclass(OldstyleClass, A))
67 self.assertFalse(issubclass(A, OldstyleClass))
68
Guido van Rossumb5591132007-09-10 22:36:02 +000069 def test_registration_basics(self):
70 class A:
71 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +000072 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +000073 pass
74 b = B()
75 self.assertEqual(issubclass(B, A), False)
76 self.assertEqual(isinstance(b, A), False)
77 A.register(B)
78 self.assertEqual(issubclass(B, A), True)
79 self.assertEqual(isinstance(b, A), True)
80 class C(B):
81 pass
82 c = C()
83 self.assertEqual(issubclass(C, A), True)
84 self.assertEqual(isinstance(c, A), True)
85
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +000086 def test_isinstance_invalidation(self):
87 class A:
88 __metaclass__ = abc.ABCMeta
89 class B(object):
90 pass
91 b = B()
92 self.assertEqual(isinstance(b, A), False)
93 A.register(B)
94 self.assertEqual(isinstance(b, A), True)
95
Guido van Rossumb5591132007-09-10 22:36:02 +000096 def test_registration_builtins(self):
97 class A:
98 __metaclass__ = abc.ABCMeta
99 A.register(int)
100 self.assertEqual(isinstance(42, A), True)
101 self.assertEqual(issubclass(int, A), True)
102 class B(A):
103 pass
104 B.register(basestring)
105 self.assertEqual(isinstance("", A), True)
106 self.assertEqual(issubclass(str, A), True)
107
108 def test_registration_edge_cases(self):
109 class A:
110 __metaclass__ = abc.ABCMeta
111 A.register(A) # should pass silently
112 class A1(A):
113 pass
114 self.assertRaises(RuntimeError, A1.register, A) # cycles not allowed
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000115 class B(object):
Guido van Rossumb5591132007-09-10 22:36:02 +0000116 pass
117 A1.register(B) # ok
118 A1.register(B) # should pass silently
119 class C(A):
120 pass
121 A.register(C) # should pass silently
122 self.assertRaises(RuntimeError, C.register, A) # cycles not allowed
123 C.register(B) # ok
124
125 def test_registration_transitiveness(self):
126 class A:
127 __metaclass__ = abc.ABCMeta
128 self.failUnless(issubclass(A, A))
129 class B:
130 __metaclass__ = abc.ABCMeta
131 self.failIf(issubclass(A, B))
132 self.failIf(issubclass(B, A))
133 class C:
134 __metaclass__ = abc.ABCMeta
135 A.register(B)
136 class B1(B):
137 pass
138 self.failUnless(issubclass(B1, A))
139 class C1(C):
140 pass
141 B1.register(C1)
142 self.failIf(issubclass(C, B))
143 self.failIf(issubclass(C, B1))
144 self.failUnless(issubclass(C1, A))
145 self.failUnless(issubclass(C1, B))
146 self.failUnless(issubclass(C1, B1))
147 C1.register(int)
148 class MyInt(int):
149 pass
150 self.failUnless(issubclass(MyInt, A))
151 self.failUnless(isinstance(42, A))
152
Guido van Rossum64c06e32007-11-22 00:55:51 +0000153 def test_all_new_methods_are_called(self):
154 class A:
155 __metaclass__ = abc.ABCMeta
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000156 class B(object):
Guido van Rossum64c06e32007-11-22 00:55:51 +0000157 counter = 0
158 def __new__(cls):
159 B.counter += 1
160 return super(B, cls).__new__(cls)
161 class C(A, B):
162 pass
163 self.assertEqual(B.counter, 0)
164 C()
165 self.assertEqual(B.counter, 1)
166
Guido van Rossumb5591132007-09-10 22:36:02 +0000167
168def test_main():
169 test_support.run_unittest(TestABC)
170
171
172if __name__ == "__main__":
173 unittest.main()