Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / amd64 / lib / python2.4 / test / test_isinstance.py
CommitLineData
920dae64
AT
1# Tests some corner cases with isinstance() and issubclass(). While these
2# tests use new style classes and properties, they actually do whitebox
3# testing of error conditions uncovered when using extension types.
4
5import unittest
6from test import test_support
7import sys
8
9
10\f
11class TestIsInstanceExceptions(unittest.TestCase):
12 # Test to make sure that an AttributeError when accessing the instance's
13 # class's bases is masked. This was actually a bug in Python 2.2 and
14 # 2.2.1 where the exception wasn't caught but it also wasn't being cleared
15 # (leading to an "undetected error" in the debug build). Set up is,
16 # isinstance(inst, cls) where:
17 #
18 # - inst isn't an InstanceType
19 # - cls isn't a ClassType, a TypeType, or a TupleType
20 # - cls has a __bases__ attribute
21 # - inst has a __class__ attribute
22 # - inst.__class__ as no __bases__ attribute
23 #
24 # Sounds complicated, I know, but this mimics a situation where an
25 # extension type raises an AttributeError when its __bases__ attribute is
26 # gotten. In that case, isinstance() should return False.
27 def test_class_has_no_bases(self):
28 class I(object):
29 def getclass(self):
30 # This must return an object that has no __bases__ attribute
31 return None
32 __class__ = property(getclass)
33
34 class C(object):
35 def getbases(self):
36 return ()
37 __bases__ = property(getbases)
38
39 self.assertEqual(False, isinstance(I(), C()))
40
41 # Like above except that inst.__class__.__bases__ raises an exception
42 # other than AttributeError
43 def test_bases_raises_other_than_attribute_error(self):
44 class E(object):
45 def getbases(self):
46 raise RuntimeError
47 __bases__ = property(getbases)
48
49 class I(object):
50 def getclass(self):
51 return E()
52 __class__ = property(getclass)
53
54 class C(object):
55 def getbases(self):
56 return ()
57 __bases__ = property(getbases)
58
59 self.assertRaises(RuntimeError, isinstance, I(), C())
60
61 # Here's a situation where getattr(cls, '__bases__') raises an exception.
62 # If that exception is not AttributeError, it should not get masked
63 def test_dont_mask_non_attribute_error(self):
64 class I: pass
65
66 class C(object):
67 def getbases(self):
68 raise RuntimeError
69 __bases__ = property(getbases)
70
71 self.assertRaises(RuntimeError, isinstance, I(), C())
72
73 # Like above, except that getattr(cls, '__bases__') raises an
74 # AttributeError, which /should/ get masked as a TypeError
75 def test_mask_attribute_error(self):
76 class I: pass
77
78 class C(object):
79 def getbases(self):
80 raise AttributeError
81 __bases__ = property(getbases)
82
83 self.assertRaises(TypeError, isinstance, I(), C())
84
85
86\f
87# These tests are similar to above, but tickle certain code paths in
88# issubclass() instead of isinstance() -- really PyObject_IsSubclass()
89# vs. PyObject_IsInstance().
90class TestIsSubclassExceptions(unittest.TestCase):
91 def test_dont_mask_non_attribute_error(self):
92 class C(object):
93 def getbases(self):
94 raise RuntimeError
95 __bases__ = property(getbases)
96
97 class S(C): pass
98
99 self.assertRaises(RuntimeError, issubclass, C(), S())
100
101 def test_mask_attribute_error(self):
102 class C(object):
103 def getbases(self):
104 raise AttributeError
105 __bases__ = property(getbases)
106
107 class S(C): pass
108
109 self.assertRaises(TypeError, issubclass, C(), S())
110
111 # Like above, but test the second branch, where the __bases__ of the
112 # second arg (the cls arg) is tested. This means the first arg must
113 # return a valid __bases__, and it's okay for it to be a normal --
114 # unrelated by inheritance -- class.
115 def test_dont_mask_non_attribute_error_in_cls_arg(self):
116 class B: pass
117
118 class C(object):
119 def getbases(self):
120 raise RuntimeError
121 __bases__ = property(getbases)
122
123 self.assertRaises(RuntimeError, issubclass, B, C())
124
125 def test_mask_attribute_error_in_cls_arg(self):
126 class B: pass
127
128 class C(object):
129 def getbases(self):
130 raise AttributeError
131 __bases__ = property(getbases)
132
133 self.assertRaises(TypeError, issubclass, B, C())
134
135
136\f
137# meta classes for creating abstract classes and instances
138class AbstractClass(object):
139 def __init__(self, bases):
140 self.bases = bases
141
142 def getbases(self):
143 return self.bases
144 __bases__ = property(getbases)
145
146 def __call__(self):
147 return AbstractInstance(self)
148
149class AbstractInstance(object):
150 def __init__(self, klass):
151 self.klass = klass
152
153 def getclass(self):
154 return self.klass
155 __class__ = property(getclass)
156
157# abstract classes
158AbstractSuper = AbstractClass(bases=())
159
160AbstractChild = AbstractClass(bases=(AbstractSuper,))
161
162# normal classes
163class Super:
164 pass
165
166class Child(Super):
167 pass
168
169# new-style classes
170class NewSuper(object):
171 pass
172
173class NewChild(NewSuper):
174 pass
175
176
177\f
178class TestIsInstanceIsSubclass(unittest.TestCase):
179 # Tests to ensure that isinstance and issubclass work on abstract
180 # classes and instances. Before the 2.2 release, TypeErrors were
181 # raised when boolean values should have been returned. The bug was
182 # triggered by mixing 'normal' classes and instances were with
183 # 'abstract' classes and instances. This case tries to test all
184 # combinations.
185
186 def test_isinstance_normal(self):
187 # normal instances
188 self.assertEqual(True, isinstance(Super(), Super))
189 self.assertEqual(False, isinstance(Super(), Child))
190 self.assertEqual(False, isinstance(Super(), AbstractSuper))
191 self.assertEqual(False, isinstance(Super(), AbstractChild))
192
193 self.assertEqual(True, isinstance(Child(), Super))
194 self.assertEqual(False, isinstance(Child(), AbstractSuper))
195
196 def test_isinstance_abstract(self):
197 # abstract instances
198 self.assertEqual(True, isinstance(AbstractSuper(), AbstractSuper))
199 self.assertEqual(False, isinstance(AbstractSuper(), AbstractChild))
200 self.assertEqual(False, isinstance(AbstractSuper(), Super))
201 self.assertEqual(False, isinstance(AbstractSuper(), Child))
202
203 self.assertEqual(True, isinstance(AbstractChild(), AbstractChild))
204 self.assertEqual(True, isinstance(AbstractChild(), AbstractSuper))
205 self.assertEqual(False, isinstance(AbstractChild(), Super))
206 self.assertEqual(False, isinstance(AbstractChild(), Child))
207
208 def test_subclass_normal(self):
209 # normal classes
210 self.assertEqual(True, issubclass(Super, Super))
211 self.assertEqual(False, issubclass(Super, AbstractSuper))
212 self.assertEqual(False, issubclass(Super, Child))
213
214 self.assertEqual(True, issubclass(Child, Child))
215 self.assertEqual(True, issubclass(Child, Super))
216 self.assertEqual(False, issubclass(Child, AbstractSuper))
217
218 def test_subclass_abstract(self):
219 # abstract classes
220 self.assertEqual(True, issubclass(AbstractSuper, AbstractSuper))
221 self.assertEqual(False, issubclass(AbstractSuper, AbstractChild))
222 self.assertEqual(False, issubclass(AbstractSuper, Child))
223
224 self.assertEqual(True, issubclass(AbstractChild, AbstractChild))
225 self.assertEqual(True, issubclass(AbstractChild, AbstractSuper))
226 self.assertEqual(False, issubclass(AbstractChild, Super))
227 self.assertEqual(False, issubclass(AbstractChild, Child))
228
229 def test_subclass_tuple(self):
230 # test with a tuple as the second argument classes
231 self.assertEqual(True, issubclass(Child, (Child,)))
232 self.assertEqual(True, issubclass(Child, (Super,)))
233 self.assertEqual(False, issubclass(Super, (Child,)))
234 self.assertEqual(True, issubclass(Super, (Child, Super)))
235 self.assertEqual(False, issubclass(Child, ()))
236 self.assertEqual(True, issubclass(Super, (Child, (Super,))))
237
238 self.assertEqual(True, issubclass(NewChild, (NewChild,)))
239 self.assertEqual(True, issubclass(NewChild, (NewSuper,)))
240 self.assertEqual(False, issubclass(NewSuper, (NewChild,)))
241 self.assertEqual(True, issubclass(NewSuper, (NewChild, NewSuper)))
242 self.assertEqual(False, issubclass(NewChild, ()))
243 self.assertEqual(True, issubclass(NewSuper, (NewChild, (NewSuper,))))
244
245 self.assertEqual(True, issubclass(int, (long, (float, int))))
246 self.assertEqual(True, issubclass(str, (unicode, (Child, NewChild, basestring))))
247
248 def test_subclass_recursion_limit(self):
249 # make sure that issubclass raises RuntimeError before the C stack is
250 # blown
251 self.assertRaises(RuntimeError, blowstack, issubclass, str, str)
252
253 def test_isinstance_recursion_limit(self):
254 # make sure that issubclass raises RuntimeError before the C stack is
255 # blown
256 self.assertRaises(RuntimeError, blowstack, isinstance, '', str)
257
258def blowstack(fxn, arg, compare_to):
259 # Make sure that calling isinstance with a deeply nested tuple for its
260 # argument will raise RuntimeError eventually.
261 tuple_arg = (compare_to,)
262 for cnt in xrange(sys.getrecursionlimit()+5):
263 tuple_arg = (tuple_arg,)
264 fxn(arg, tuple_arg)
265
266\f
267def test_main():
268 test_support.run_unittest(
269 TestIsInstanceExceptions,
270 TestIsSubclassExceptions,
271 TestIsInstanceIsSubclass
272 )
273
274
275if __name__ == '__main__':
276 test_main()