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

Delta Between Two Patch Sets: Lib/test/test_abc.py

Issue 11610: Improving property to accept abstract methods
Left Patch Set: Created 8 years, 4 months ago
Right 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/numbers.py ('k') | Lib/test/test_property.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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 14
15 def test_abstractmethod_basics(self): 15 def test_abstractproperty_basics(self):
16 @abc.abstractmethod 16 @abc.abstractproperty
17 def foo(self): pass 17 def foo(self): pass
18 self.assertTrue(foo.__isabstractmethod__) 18 self.assertTrue(foo.__isabstractmethod__)
19 def bar(self): pass 19 def bar(self): pass
20 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) 20 self.assertFalse(hasattr(bar, "__isabstractmethod__"))
Benjamin Peterson 2011/11/29 17:27:46 Why is the default needed?
dsdale24 2011/11/29 17:40:05 Because function objects do not define __isabstrac
21 21
22 def test_abstractproperty_basics(self): 22 class C(metaclass=abc.ABCMeta):
23 @property 23 @abc.abstractproperty
24 @abc.abstractmethod 24 def foo(self): return 3
25 def foo(self): pass 25 self.assertRaises(TypeError, C)
26 self.assertTrue(foo.__isabstractmethod__) 26 class D(C):
27 def bar(self): pass
28 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
29
30 class C(metaclass=abc.ABCMeta):
31 @property 27 @property
32 @abc.abstractmethod
33 def foo(self): return 3
34 self.assertRaises(TypeError, C)
35 class D(C):
36 @C.foo.getter
37 def foo(self): return super().foo 28 def foo(self): return super().foo
38 self.assertEqual(D().foo, 3) 29 self.assertEqual(D().foo, 3)
30 self.assertFalse(getattr(D.foo, "__isabstractmethod__", False))
39 31
40 def test_abstractclassmethod_basics(self): 32 def test_abstractclassmethod_basics(self):
41 @classmethod 33 @abc.abstractclassmethod
42 @abc.abstractmethod
43 def foo(cls): pass 34 def foo(cls): pass
44 self.assertTrue(foo.__isabstractmethod__) 35 self.assertTrue(foo.__isabstractmethod__)
45 @classmethod 36 @classmethod
46 def bar(cls): pass 37 def bar(cls): pass
47 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) 38 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
48 39
49 class C(metaclass=abc.ABCMeta): 40 class C(metaclass=abc.ABCMeta):
50 @classmethod 41 @abc.abstractclassmethod
51 @abc.abstractmethod
52 def foo(cls): return cls.__name__ 42 def foo(cls): return cls.__name__
53 self.assertRaises(TypeError, C) 43 self.assertRaises(TypeError, C)
54 class D(C): 44 class D(C):
55 @classmethod 45 @classmethod
56 def foo(cls): return super().foo() 46 def foo(cls): return super().foo()
57 self.assertEqual(D.foo(), 'D') 47 self.assertEqual(D.foo(), 'D')
58 self.assertEqual(D().foo(), 'D') 48 self.assertEqual(D().foo(), 'D')
59 49
60 def test_abstractstaticmethod_basics(self): 50 def test_abstractstaticmethod_basics(self):
61 @staticmethod 51 @abc.abstractstaticmethod
62 @abc.abstractmethod
63 def foo(): pass 52 def foo(): pass
64 self.assertTrue(foo.__isabstractmethod__) 53 self.assertTrue(foo.__isabstractmethod__)
65 @staticmethod 54 @staticmethod
66 def bar(): pass 55 def bar(): pass
67 self.assertFalse(getattr(bar, "__isabstractmethod__", False)) 56 self.assertFalse(getattr(bar, "__isabstractmethod__", False))
68 57
69 class C(metaclass=abc.ABCMeta): 58 class C(metaclass=abc.ABCMeta):
70 @staticmethod 59 @abc.abstractstaticmethod
71 @abc.abstractmethod
72 def foo(): return 3 60 def foo(): return 3
73 self.assertRaises(TypeError, C) 61 self.assertRaises(TypeError, C)
74 class D(C): 62 class D(C):
75 @staticmethod 63 @staticmethod
76 def foo(): return 4 64 def foo(): return 4
77 self.assertEqual(D.foo(), 4) 65 self.assertEqual(D.foo(), 4)
78 self.assertEqual(D().foo(), 4) 66 self.assertEqual(D().foo(), 4)
79 67
80 def test_abstractmethod_integration(self): 68 def test_abstractmethod_integration(self):
69 for abstractthing in [abc.abstractmethod, abc.abstractproperty,
70 abc.abstractclassmethod,
71 abc.abstractstaticmethod]:
81 class C(metaclass=abc.ABCMeta): 72 class C(metaclass=abc.ABCMeta):
82 @abc.abstractmethod 73 @abstractthing
83 def foo(self): pass # abstract 74 def foo(self): pass # abstract
84 def bar(self): pass # concrete 75 def bar(self): pass # concrete
85 self.assertEqual(C.__abstractmethods__, {"foo"}) 76 self.assertEqual(C.__abstractmethods__, {"foo"})
86 self.assertRaises(TypeError, C) # because foo is abstract 77 self.assertRaises(TypeError, C) # because foo is abstract
87 self.assertTrue(isabstract(C)) 78 self.assertTrue(isabstract(C))
88 class D(C): 79 class D(C):
89 def bar(self): pass # concrete override of concrete 80 def bar(self): pass # concrete override of concrete
90 self.assertEqual(D.__abstractmethods__, {"foo"}) 81 self.assertEqual(D.__abstractmethods__, {"foo"})
91 self.assertRaises(TypeError, D) # because foo is still abstract 82 self.assertRaises(TypeError, D) # because foo is still abstract
92 self.assertTrue(isabstract(D)) 83 self.assertTrue(isabstract(D))
93 class E(D): 84 class E(D):
94 def foo(self): pass 85 def foo(self): pass
95 self.assertEqual(E.__abstractmethods__, set()) 86 self.assertEqual(E.__abstractmethods__, set())
96 E() # now foo is concrete, too 87 E() # now foo is concrete, too
97 self.assertFalse(isabstract(E)) 88 self.assertFalse(isabstract(E))
98 class F(E): 89 class F(E):
99 @abc.abstractmethod 90 @abstractthing
91 def bar(self): pass # abstract override of concrete
92 self.assertEqual(F.__abstractmethods__, {"bar"})
93 self.assertRaises(TypeError, F) # because bar is abstract now
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
100 def bar(self): pass # abstract override of concrete 187 def bar(self): pass # abstract override of concrete
101 self.assertEqual(F.__abstractmethods__, {"bar"}) 188 self.assertEqual(F.__abstractmethods__, {"bar"})
102 self.assertRaises(TypeError, F) # because bar is abstract now 189 self.assertRaises(TypeError, F) # because bar is abstract now
103 self.assertTrue(isabstract(F)) 190 self.assertTrue(isabstract(F))
104 191
105 def test_descriptors_with_abstractmethod(self): 192 def test_descriptors_with_abstractmethod(self):
106 class C(metaclass=abc.ABCMeta): 193 class C(metaclass=abc.ABCMeta):
107 @property 194 @property
108 @abc.abstractmethod 195 @abc.abstractmethod
109 def foo(self): return 3 196 def foo(self): return 3
(...skipping 21 matching lines...) Expand all
131 pass 218 pass
132 bar.__isabstractmethod__ = NotBool() 219 bar.__isabstractmethod__ = NotBool()
133 foo = property(bar) 220 foo = property(bar)
134 221
135 222
136 def test_customdescriptors_with_abstractmethod(self): 223 def test_customdescriptors_with_abstractmethod(self):
137 class Descriptor: 224 class Descriptor:
138 def __init__(self, fget, fset=None): 225 def __init__(self, fget, fset=None):
139 self._fget = fget 226 self._fget = fget
140 self._fset = fset 227 self._fset = fset
141 def getter(self, callable): return Descriptor(callable, self._fget) 228 def getter(self, callable):
Benjamin Peterson 2011/11/29 02:45:54 Split lines.
142 def setter(self, callable): return Descriptor(self._fget, callable) 229 return Descriptor(callable, self._fget)
230 def setter(self, callable):
231 return Descriptor(self._fget, callable)
143 @property 232 @property
144 def __isabstractmethod__(self): 233 def __isabstractmethod__(self):
145 return (getattr(self._fget, '__isabstractmethod__', False) 234 return (getattr(self._fget, '__isabstractmethod__', False)
146 or getattr(self._fset, '__isabstractmethod__', False)) 235 or getattr(self._fset, '__isabstractmethod__', False))
147 class C(metaclass=abc.ABCMeta): 236 class C(metaclass=abc.ABCMeta):
148 @Descriptor 237 @Descriptor
149 @abc.abstractmethod 238 @abc.abstractmethod
150 def foo(self): return 3 239 def foo(self): return 3
151 @foo.setter 240 @foo.setter
152 @abc.abstractmethod 241 @abc.abstractmethod
153 def foo(self, val): pass 242 def foo(self, val): pass
154 self.assertRaises(TypeError, C) 243 self.assertRaises(TypeError, C)
155 class D(C): 244 class D(C):
156 @C.foo.getter 245 @C.foo.getter
157 def foo(self): return super().foo 246 def foo(self): return super().foo
158 self.assertRaises(TypeError, D) 247 self.assertRaises(TypeError, D)
159 class E(D): 248 class E(D):
160 @D.foo.setter 249 @D.foo.setter
161 def foo(self, val): pass 250 def foo(self, val): pass
162 self.assertEqual(E.foo.__isabstractmethod__, False) 251 self.assertFalse(E.foo.__isabstractmethod__)
Benjamin Peterson 2011/11/29 02:45:54 Use assertFalse instead.
163 252
164 def test_metaclass_abc(self): 253 def test_metaclass_abc(self):
165 # Metaclasses can be ABCs, too. 254 # Metaclasses can be ABCs, too.
166 class A(metaclass=abc.ABCMeta): 255 class A(metaclass=abc.ABCMeta):
167 @abc.abstractmethod 256 @abc.abstractmethod
168 def x(self): 257 def x(self):
169 pass 258 pass
170 self.assertEqual(A.__abstractmethods__, {"x"}) 259 self.assertEqual(A.__abstractmethods__, {"x"})
171 class meta(type, A): 260 class meta(type, A):
172 def x(self): 261 def x(self):
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 C() 415 C()
327 self.assertEqual(B.counter, 1) 416 self.assertEqual(B.counter, 1)
328 417
329 418
330 def test_main(): 419 def test_main():
331 support.run_unittest(TestABC) 420 support.run_unittest(TestABC)
332 421
333 422
334 if __name__ == "__main__": 423 if __name__ == "__main__":
335 unittest.main() 424 unittest.main()
LEFTRIGHT

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