Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(164933)

Side by Side Diff: Lib/test/test_abc.py

Issue 11610: Improving property to accept abstract methods
Patch Set: Created 8 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/numbers.py ('k') | Lib/test/test_property.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2007 Google, Inc. All Rights Reserved. 1 # Copyright 2007 Google, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement. 2 # Licensed to PSF under a Contributor Agreement.
3 3
4 """Unit tests for abc.py.""" 4 """Unit tests for abc.py."""
5 5
6 import unittest 6 import unittest
7 from test import support 7 from test import support
8 8
9 import abc 9 import abc
10 from inspect import isabstract 10 from inspect import isabstract
11 11
12 12
13 class TestABC(unittest.TestCase): 13 class TestLegacyAPI(unittest.TestCase):
14
15 def test_abstractmethod_basics(self):
16 @abc.abstractmethod
17 def foo(self): pass
18 self.assertTrue(foo.__isabstractmethod__)
19 def bar(self): pass
20 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
21 14
22 def test_abstractproperty_basics(self): 15 def test_abstractproperty_basics(self):
23 @abc.abstractproperty 16 @abc.abstractproperty
24 def foo(self): pass 17 def foo(self): pass
25 self.assertTrue(foo.__isabstractmethod__) 18 self.assertTrue(foo.__isabstractmethod__)
26 def bar(self): pass 19 def bar(self): pass
27 self.assertFalse(hasattr(bar, "__isabstractmethod__")) 20 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
28 21
29 class C(metaclass=abc.ABCMeta): 22 class C(metaclass=abc.ABCMeta):
30 @abc.abstractproperty 23 @abc.abstractproperty
31 def foo(self): return 3 24 def foo(self): return 3
25 self.assertRaises(TypeError, C)
32 class D(C): 26 class D(C):
33 @property 27 @property
34 def foo(self): return super().foo 28 def foo(self): return super().foo
35 self.assertEqual(D().foo, 3) 29 self.assertEqual(D().foo, 3)
30 self.assertFalse(getattr(D.foo, "__isabstractmethod__", False))
36 31
37 def test_abstractclassmethod_basics(self): 32 def test_abstractclassmethod_basics(self):
38 @abc.abstractclassmethod 33 @abc.abstractclassmethod
39 def foo(cls): pass 34 def foo(cls): pass
40 self.assertTrue(foo.__isabstractmethod__) 35 self.assertTrue(foo.__isabstractmethod__)
41 @classmethod 36 @classmethod
42 def bar(cls): pass 37 def bar(cls): pass
43 self.assertFalse(hasattr(bar, "__isabstractmethod__")) 38 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
44 39
45 class C(metaclass=abc.ABCMeta): 40 class C(metaclass=abc.ABCMeta):
46 @abc.abstractclassmethod 41 @abc.abstractclassmethod
47 def foo(cls): return cls.__name__ 42 def foo(cls): return cls.__name__
48 self.assertRaises(TypeError, C) 43 self.assertRaises(TypeError, C)
49 class D(C): 44 class D(C):
50 @classmethod 45 @classmethod
51 def foo(cls): return super().foo() 46 def foo(cls): return super().foo()
52 self.assertEqual(D.foo(), 'D') 47 self.assertEqual(D.foo(), 'D')
53 self.assertEqual(D().foo(), 'D') 48 self.assertEqual(D().foo(), 'D')
54 49
55 def test_abstractstaticmethod_basics(self): 50 def test_abstractstaticmethod_basics(self):
56 @abc.abstractstaticmethod 51 @abc.abstractstaticmethod
57 def foo(): pass 52 def foo(): pass
58 self.assertTrue(foo.__isabstractmethod__) 53 self.assertTrue(foo.__isabstractmethod__)
59 @staticmethod 54 @staticmethod
60 def bar(): pass 55 def bar(): pass
61 self.assertFalse(hasattr(bar, "__isabstractmethod__")) 56 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
62 57
63 class C(metaclass=abc.ABCMeta): 58 class C(metaclass=abc.ABCMeta):
64 @abc.abstractstaticmethod 59 @abc.abstractstaticmethod
65 def foo(): return 3 60 def foo(): return 3
66 self.assertRaises(TypeError, C) 61 self.assertRaises(TypeError, C)
67 class D(C): 62 class D(C):
68 @staticmethod 63 @staticmethod
69 def foo(): return 4 64 def foo(): return 4
70 self.assertEqual(D.foo(), 4) 65 self.assertEqual(D.foo(), 4)
71 self.assertEqual(D().foo(), 4) 66 self.assertEqual(D().foo(), 4)
(...skipping 18 matching lines...) Expand all
90 def foo(self): pass 85 def foo(self): pass
91 self.assertEqual(E.__abstractmethods__, set()) 86 self.assertEqual(E.__abstractmethods__, set())
92 E() # now foo is concrete, too 87 E() # now foo is concrete, too
93 self.assertFalse(isabstract(E)) 88 self.assertFalse(isabstract(E))
94 class F(E): 89 class F(E):
95 @abstractthing 90 @abstractthing
96 def bar(self): pass # abstract override of concrete 91 def bar(self): pass # abstract override of concrete
97 self.assertEqual(F.__abstractmethods__, {"bar"}) 92 self.assertEqual(F.__abstractmethods__, {"bar"})
98 self.assertRaises(TypeError, F) # because bar is abstract now 93 self.assertRaises(TypeError, F) # because bar is abstract now
99 self.assertTrue(isabstract(F)) 94 self.assertTrue(isabstract(F))
95
96
97 class TestABC(unittest.TestCase):
98
99 def test_abstractmethod_basics(self):
100 @abc.abstractmethod
101 def foo(self): pass
102 self.assertTrue(foo.__isabstractmethod__)
103 def bar(self): pass
104 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
105
106 def test_abstractproperty_basics(self):
107 @property
108 @abc.abstractmethod
109 def foo(self): pass
110 self.assertTrue(foo.__isabstractmethod__)
111 def bar(self): pass
112 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
113
114 class C(metaclass=abc.ABCMeta):
115 @property
116 @abc.abstractmethod
117 def foo(self): return 3
118 self.assertRaises(TypeError, C)
119 class D(C):
120 @C.foo.getter
121 def foo(self): return super().foo
122 self.assertEqual(D().foo, 3)
123
124 def test_abstractclassmethod_basics(self):
125 @classmethod
126 @abc.abstractmethod
127 def foo(cls): pass
128 self.assertTrue(foo.__isabstractmethod__)
129 @classmethod
130 def bar(cls): pass
131 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
132
133 class C(metaclass=abc.ABCMeta):
134 @classmethod
135 @abc.abstractmethod
136 def foo(cls): return cls.__name__
137 self.assertRaises(TypeError, C)
138 class D(C):
139 @classmethod
140 def foo(cls): return super().foo()
141 self.assertEqual(D.foo(), 'D')
142 self.assertEqual(D().foo(), 'D')
143
144 def test_abstractstaticmethod_basics(self):
145 @staticmethod
146 @abc.abstractmethod
147 def foo(): pass
148 self.assertTrue(foo.__isabstractmethod__)
149 @staticmethod
150 def bar(): pass
151 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
152
153 class C(metaclass=abc.ABCMeta):
154 @staticmethod
155 @abc.abstractmethod
156 def foo(): return 3
157 self.assertRaises(TypeError, C)
158 class D(C):
159 @staticmethod
160 def foo(): return 4
161 self.assertEqual(D.foo(), 4)
162 self.assertEqual(D().foo(), 4)
163
164 def test_abstractmethod_integration(self):
165 for abstractthing in [abc.abstractmethod, abc.abstractproperty,
166 abc.abstractclassmethod,
167 abc.abstractstaticmethod]:
168 class C(metaclass=abc.ABCMeta):
169 @abstractthing
170 def foo(self): pass # abstract
171 def bar(self): pass # concrete
172 self.assertEqual(C.__abstractmethods__, {"foo"})
173 self.assertRaises(TypeError, C) # because foo is abstract
174 self.assertTrue(isabstract(C))
175 class D(C):
176 def bar(self): pass # concrete override of concrete
177 self.assertEqual(D.__abstractmethods__, {"foo"})
178 self.assertRaises(TypeError, D) # because foo is still abstract
179 self.assertTrue(isabstract(D))
180 class E(D):
181 def foo(self): pass
182 self.assertEqual(E.__abstractmethods__, set())
183 E() # now foo is concrete, too
184 self.assertFalse(isabstract(E))
185 class F(E):
186 @abstractthing
187 def bar(self): pass # abstract override of concrete
188 self.assertEqual(F.__abstractmethods__, {"bar"})
189 self.assertRaises(TypeError, F) # because bar is abstract now
190 self.assertTrue(isabstract(F))
191
192 def test_descriptors_with_abstractmethod(self):
193 class C(metaclass=abc.ABCMeta):
194 @property
195 @abc.abstractmethod
196 def foo(self): return 3
197 @foo.setter
198 @abc.abstractmethod
199 def foo(self, val): pass
200 self.assertRaises(TypeError, C)
201 class D(C):
202 @C.foo.getter
203 def foo(self): return super().foo
204 self.assertRaises(TypeError, D)
205 class E(D):
206 @D.foo.setter
207 def foo(self, val): pass
208 self.assertEqual(E().foo, 3)
209 # check that the property's __isabstractmethod__ descriptor does the
210 # right thing when presented with a value that fails truth testing:
211 class NotBool(object):
212 def __nonzero__(self):
213 raise ValueError()
214 __len__ = __nonzero__
215 with self.assertRaises(ValueError):
216 class F(C):
217 def bar(self):
218 pass
219 bar.__isabstractmethod__ = NotBool()
220 foo = property(bar)
221
222
223 def test_customdescriptors_with_abstractmethod(self):
224 class Descriptor:
225 def __init__(self, fget, fset=None):
226 self._fget = fget
227 self._fset = fset
228 def getter(self, callable):
229 return Descriptor(callable, self._fget)
230 def setter(self, callable):
231 return Descriptor(self._fget, callable)
232 @property
233 def __isabstractmethod__(self):
234 return (getattr(self._fget, '__isabstractmethod__', False)
235 or getattr(self._fset, '__isabstractmethod__', False))
236 class C(metaclass=abc.ABCMeta):
237 @Descriptor
238 @abc.abstractmethod
239 def foo(self): return 3
240 @foo.setter
241 @abc.abstractmethod
242 def foo(self, val): pass
243 self.assertRaises(TypeError, C)
244 class D(C):
245 @C.foo.getter
246 def foo(self): return super().foo
247 self.assertRaises(TypeError, D)
248 class E(D):
249 @D.foo.setter
250 def foo(self, val): pass
251 self.assertFalse(E.foo.__isabstractmethod__)
100 252
101 def test_metaclass_abc(self): 253 def test_metaclass_abc(self):
102 # Metaclasses can be ABCs, too. 254 # Metaclasses can be ABCs, too.
103 class A(metaclass=abc.ABCMeta): 255 class A(metaclass=abc.ABCMeta):
104 @abc.abstractmethod 256 @abc.abstractmethod
105 def x(self): 257 def x(self):
106 pass 258 pass
107 self.assertEqual(A.__abstractmethods__, {"x"}) 259 self.assertEqual(A.__abstractmethods__, {"x"})
108 class meta(type, A): 260 class meta(type, A):
109 def x(self): 261 def x(self):
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 C() 415 C()
264 self.assertEqual(B.counter, 1) 416 self.assertEqual(B.counter, 1)
265 417
266 418
267 def test_main(): 419 def test_main():
268 support.run_unittest(TestABC) 420 support.run_unittest(TestABC)
269 421
270 422
271 if __name__ == "__main__": 423 if __name__ == "__main__":
272 unittest.main() 424 unittest.main()
OLDNEW
« no previous file with comments | « Lib/numbers.py ('k') | Lib/test/test_property.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+