blob: e3883d67b76c2df573de1da8fe7cb7f750645171 [file] [log] [blame]
Thomas Wouters1d75a792000-08-17 22:37:32 +00001"Test the functionality of Python classes implementing operators."
2
Thomas Woutersed03b412007-08-28 21:37:11 +00003import unittest
Thomas Woutersed03b412007-08-28 21:37:11 +00004
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Wouters1d75a792000-08-17 22:37:32 +00006
7testmeths = [
8
9# Binary operations
10 "add",
11 "radd",
12 "sub",
13 "rsub",
14 "mul",
15 "rmul",
Neal Norwitzbcc0db82006-03-24 08:14:36 +000016 "truediv",
17 "rtruediv",
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +020018 "floordiv",
19 "rfloordiv",
Thomas Wouters1d75a792000-08-17 22:37:32 +000020 "mod",
21 "rmod",
22 "divmod",
23 "rdivmod",
24 "pow",
25 "rpow",
26 "rshift",
27 "rrshift",
28 "lshift",
29 "rlshift",
30 "and",
31 "rand",
32 "or",
33 "ror",
34 "xor",
35 "rxor",
36
37# List/dict operations
38 "contains",
39 "getitem",
Thomas Wouters1d75a792000-08-17 22:37:32 +000040 "setitem",
Thomas Wouters1d75a792000-08-17 22:37:32 +000041 "delitem",
Thomas Wouters1d75a792000-08-17 22:37:32 +000042
43# Unary operations
44 "neg",
45 "pos",
46 "abs",
Thomas Wouters1d75a792000-08-17 22:37:32 +000047
48# generic operations
49 "init",
Thomas Wouters1d75a792000-08-17 22:37:32 +000050 ]
51
52# These need to return something other than None
Thomas Wouters1d75a792000-08-17 22:37:32 +000053# "hash",
54# "str",
55# "repr",
Neil Schemenauer3a313e32004-07-19 16:29:17 +000056# "int",
Neil Schemenauer3a313e32004-07-19 16:29:17 +000057# "float",
Thomas Wouters1d75a792000-08-17 22:37:32 +000058
59# These are separate because they can influence the test of other methods.
60# "getattr",
61# "setattr",
62# "delattr",
63
Thomas Woutersed03b412007-08-28 21:37:11 +000064callLst = []
65def trackCall(f):
66 def track(*args, **kwargs):
67 callLst.append((f.__name__, args))
68 return f(*args, **kwargs)
69 return track
Thomas Wouters1d75a792000-08-17 22:37:32 +000070
Thomas Woutersed03b412007-08-28 21:37:11 +000071statictests = """
72@trackCall
73def __hash__(self, *args):
74 return hash(id(self))
Thomas Wouters1d75a792000-08-17 22:37:32 +000075
Thomas Woutersed03b412007-08-28 21:37:11 +000076@trackCall
77def __str__(self, *args):
78 return "AllTests"
Thomas Wouters1d75a792000-08-17 22:37:32 +000079
Thomas Woutersed03b412007-08-28 21:37:11 +000080@trackCall
81def __repr__(self, *args):
82 return "AllTests"
Neil Schemenauer3a313e32004-07-19 16:29:17 +000083
Thomas Woutersed03b412007-08-28 21:37:11 +000084@trackCall
85def __int__(self, *args):
86 return 1
Guido van Rossumcd16bf62007-06-13 18:07:49 +000087
Thomas Woutersed03b412007-08-28 21:37:11 +000088@trackCall
89def __index__(self, *args):
90 return 1
Neil Schemenauer3a313e32004-07-19 16:29:17 +000091
Thomas Woutersed03b412007-08-28 21:37:11 +000092@trackCall
93def __float__(self, *args):
94 return 1.0
Thomas Wouters1d75a792000-08-17 22:37:32 +000095
Thomas Woutersed03b412007-08-28 21:37:11 +000096@trackCall
Thomas Woutersed03b412007-08-28 21:37:11 +000097def __eq__(self, *args):
98 return True
Guido van Rossum47b9ff62006-08-24 00:41:19 +000099
Thomas Woutersed03b412007-08-28 21:37:11 +0000100@trackCall
101def __ne__(self, *args):
102 return False
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000103
Thomas Woutersed03b412007-08-28 21:37:11 +0000104@trackCall
105def __lt__(self, *args):
106 return False
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000107
Thomas Woutersed03b412007-08-28 21:37:11 +0000108@trackCall
109def __le__(self, *args):
110 return True
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000111
Thomas Woutersed03b412007-08-28 21:37:11 +0000112@trackCall
113def __gt__(self, *args):
114 return False
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000115
Thomas Woutersed03b412007-08-28 21:37:11 +0000116@trackCall
117def __ge__(self, *args):
118 return True
119"""
Barry Warsaw07d8d642001-08-20 20:29:07 +0000120
Thomas Woutersed03b412007-08-28 21:37:11 +0000121# Synthesize all the other AllTests methods from the names in testmeths.
Tim Peters01705212001-12-11 19:28:47 +0000122
123method_template = """\
Thomas Woutersed03b412007-08-28 21:37:11 +0000124@trackCall
125def __%s__(self, *args):
126 pass
Tim Peters01705212001-12-11 19:28:47 +0000127"""
128
Thomas Wouters4cdada92006-04-15 09:19:16 +0000129d = {}
Thomas Woutersed03b412007-08-28 21:37:11 +0000130exec(statictests, globals(), d)
Thomas Wouters1d75a792000-08-17 22:37:32 +0000131for method in testmeths:
Thomas Woutersed03b412007-08-28 21:37:11 +0000132 exec(method_template % method, globals(), d)
133AllTests = type("AllTests", (object,), d)
134del d, statictests, method, method_template
Thomas Wouters1d75a792000-08-17 22:37:32 +0000135
Thomas Woutersed03b412007-08-28 21:37:11 +0000136class ClassTests(unittest.TestCase):
137 def setUp(self):
138 callLst[:] = []
Thomas Wouters1d75a792000-08-17 22:37:32 +0000139
Thomas Woutersed03b412007-08-28 21:37:11 +0000140 def assertCallStack(self, expected_calls):
141 actualCallList = callLst[:] # need to copy because the comparison below will add
142 # additional calls to callLst
143 if expected_calls != actualCallList:
144 self.fail("Expected call list:\n %s\ndoes not match actual call list\n %s" %
145 (expected_calls, actualCallList))
Thomas Wouters1d75a792000-08-17 22:37:32 +0000146
Thomas Woutersed03b412007-08-28 21:37:11 +0000147 def testInit(self):
148 foo = AllTests()
149 self.assertCallStack([("__init__", (foo,))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000150
Thomas Woutersed03b412007-08-28 21:37:11 +0000151 def testBinaryOps(self):
152 testme = AllTests()
153 # Binary operations
Thomas Wouters1d75a792000-08-17 22:37:32 +0000154
Thomas Woutersed03b412007-08-28 21:37:11 +0000155 callLst[:] = []
156 testme + 1
157 self.assertCallStack([("__add__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000158
Thomas Woutersed03b412007-08-28 21:37:11 +0000159 callLst[:] = []
160 1 + testme
161 self.assertCallStack([("__radd__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000162
Thomas Woutersed03b412007-08-28 21:37:11 +0000163 callLst[:] = []
164 testme - 1
165 self.assertCallStack([("__sub__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000166
Thomas Woutersed03b412007-08-28 21:37:11 +0000167 callLst[:] = []
168 1 - testme
169 self.assertCallStack([("__rsub__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000170
Thomas Woutersed03b412007-08-28 21:37:11 +0000171 callLst[:] = []
172 testme * 1
173 self.assertCallStack([("__mul__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000174
Thomas Woutersed03b412007-08-28 21:37:11 +0000175 callLst[:] = []
176 1 * testme
177 self.assertCallStack([("__rmul__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000178
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200179 callLst[:] = []
180 testme / 1
181 self.assertCallStack([("__truediv__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000182
183
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200184 callLst[:] = []
185 1 / testme
186 self.assertCallStack([("__rtruediv__", (testme, 1))])
187
188 callLst[:] = []
189 testme // 1
190 self.assertCallStack([("__floordiv__", (testme, 1))])
191
192
193 callLst[:] = []
194 1 // testme
195 self.assertCallStack([("__rfloordiv__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000196
Thomas Woutersed03b412007-08-28 21:37:11 +0000197 callLst[:] = []
198 testme % 1
199 self.assertCallStack([("__mod__", (testme, 1))])
Thomas Wouters89f507f2006-12-13 04:49:30 +0000200
Thomas Woutersed03b412007-08-28 21:37:11 +0000201 callLst[:] = []
202 1 % testme
203 self.assertCallStack([("__rmod__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000204
205
Thomas Woutersed03b412007-08-28 21:37:11 +0000206 callLst[:] = []
207 divmod(testme,1)
208 self.assertCallStack([("__divmod__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000209
Thomas Woutersed03b412007-08-28 21:37:11 +0000210 callLst[:] = []
211 divmod(1, testme)
212 self.assertCallStack([("__rdivmod__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000213
Thomas Woutersed03b412007-08-28 21:37:11 +0000214 callLst[:] = []
215 testme ** 1
216 self.assertCallStack([("__pow__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000217
Thomas Woutersed03b412007-08-28 21:37:11 +0000218 callLst[:] = []
219 1 ** testme
220 self.assertCallStack([("__rpow__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000221
Thomas Woutersed03b412007-08-28 21:37:11 +0000222 callLst[:] = []
223 testme >> 1
224 self.assertCallStack([("__rshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000225
Thomas Woutersed03b412007-08-28 21:37:11 +0000226 callLst[:] = []
227 1 >> testme
228 self.assertCallStack([("__rrshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000229
Thomas Woutersed03b412007-08-28 21:37:11 +0000230 callLst[:] = []
231 testme << 1
232 self.assertCallStack([("__lshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000233
Thomas Woutersed03b412007-08-28 21:37:11 +0000234 callLst[:] = []
235 1 << testme
236 self.assertCallStack([("__rlshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000237
Thomas Woutersed03b412007-08-28 21:37:11 +0000238 callLst[:] = []
239 testme & 1
240 self.assertCallStack([("__and__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000241
Thomas Woutersed03b412007-08-28 21:37:11 +0000242 callLst[:] = []
243 1 & testme
244 self.assertCallStack([("__rand__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000245
Thomas Woutersed03b412007-08-28 21:37:11 +0000246 callLst[:] = []
247 testme | 1
248 self.assertCallStack([("__or__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000249
Thomas Woutersed03b412007-08-28 21:37:11 +0000250 callLst[:] = []
251 1 | testme
252 self.assertCallStack([("__ror__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000253
Thomas Woutersed03b412007-08-28 21:37:11 +0000254 callLst[:] = []
255 testme ^ 1
256 self.assertCallStack([("__xor__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000257
Thomas Woutersed03b412007-08-28 21:37:11 +0000258 callLst[:] = []
259 1 ^ testme
260 self.assertCallStack([("__rxor__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000261
Thomas Woutersed03b412007-08-28 21:37:11 +0000262 def testListAndDictOps(self):
263 testme = AllTests()
264
265 # List/dict operations
266
267 class Empty: pass
268
269 try:
270 1 in Empty()
271 self.fail('failed, should have raised TypeError')
272 except TypeError:
273 pass
274
275 callLst[:] = []
276 1 in testme
277 self.assertCallStack([('__contains__', (testme, 1))])
278
279 callLst[:] = []
280 testme[1]
281 self.assertCallStack([('__getitem__', (testme, 1))])
282
283 callLst[:] = []
284 testme[1] = 1
285 self.assertCallStack([('__setitem__', (testme, 1, 1))])
286
287 callLst[:] = []
288 del testme[1]
289 self.assertCallStack([('__delitem__', (testme, 1))])
290
291 callLst[:] = []
292 testme[:42]
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000293 self.assertCallStack([('__getitem__', (testme, slice(None, 42)))])
Thomas Woutersed03b412007-08-28 21:37:11 +0000294
295 callLst[:] = []
296 testme[:42] = "The Answer"
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000297 self.assertCallStack([('__setitem__', (testme, slice(None, 42),
298 "The Answer"))])
Thomas Woutersed03b412007-08-28 21:37:11 +0000299
300 callLst[:] = []
301 del testme[:42]
Thomas Woutersd2cf20e2007-08-30 22:57:53 +0000302 self.assertCallStack([('__delitem__', (testme, slice(None, 42)))])
Thomas Woutersed03b412007-08-28 21:37:11 +0000303
304 callLst[:] = []
305 testme[2:1024:10]
306 self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
307
308 callLst[:] = []
309 testme[2:1024:10] = "A lot"
310 self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
311 "A lot"))])
312 callLst[:] = []
313 del testme[2:1024:10]
314 self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
315
316 callLst[:] = []
317 testme[:42, ..., :24:, 24, 100]
318 self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
319 Ellipsis,
320 slice(None, 24, None),
321 24, 100)))])
322 callLst[:] = []
323 testme[:42, ..., :24:, 24, 100] = "Strange"
324 self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
325 Ellipsis,
326 slice(None, 24, None),
327 24, 100), "Strange"))])
328 callLst[:] = []
329 del testme[:42, ..., :24:, 24, 100]
330 self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
331 Ellipsis,
332 slice(None, 24, None),
333 24, 100)))])
334
Thomas Woutersed03b412007-08-28 21:37:11 +0000335 def testUnaryOps(self):
336 testme = AllTests()
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000337
Thomas Woutersed03b412007-08-28 21:37:11 +0000338 callLst[:] = []
339 -testme
340 self.assertCallStack([('__neg__', (testme,))])
341 callLst[:] = []
342 +testme
343 self.assertCallStack([('__pos__', (testme,))])
344 callLst[:] = []
345 abs(testme)
346 self.assertCallStack([('__abs__', (testme,))])
347 callLst[:] = []
348 int(testme)
349 self.assertCallStack([('__int__', (testme,))])
350 callLst[:] = []
351 float(testme)
352 self.assertCallStack([('__float__', (testme,))])
353 callLst[:] = []
354 oct(testme)
355 self.assertCallStack([('__index__', (testme,))])
356 callLst[:] = []
357 hex(testme)
358 self.assertCallStack([('__index__', (testme,))])
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000359
360
Thomas Woutersed03b412007-08-28 21:37:11 +0000361 def testMisc(self):
362 testme = AllTests()
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000363
Thomas Woutersed03b412007-08-28 21:37:11 +0000364 callLst[:] = []
365 hash(testme)
366 self.assertCallStack([('__hash__', (testme,))])
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000367
Thomas Woutersed03b412007-08-28 21:37:11 +0000368 callLst[:] = []
369 repr(testme)
370 self.assertCallStack([('__repr__', (testme,))])
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000371
Thomas Woutersed03b412007-08-28 21:37:11 +0000372 callLst[:] = []
373 str(testme)
374 self.assertCallStack([('__str__', (testme,))])
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000375
Thomas Woutersed03b412007-08-28 21:37:11 +0000376 callLst[:] = []
377 testme == 1
378 self.assertCallStack([('__eq__', (testme, 1))])
379
380 callLst[:] = []
381 testme < 1
382 self.assertCallStack([('__lt__', (testme, 1))])
383
384 callLst[:] = []
385 testme > 1
386 self.assertCallStack([('__gt__', (testme, 1))])
387
388 callLst[:] = []
389 testme != 1
390 self.assertCallStack([('__ne__', (testme, 1))])
391
392 callLst[:] = []
393 1 == testme
394 self.assertCallStack([('__eq__', (1, testme))])
395
396 callLst[:] = []
397 1 < testme
398 self.assertCallStack([('__gt__', (1, testme))])
399
400 callLst[:] = []
401 1 > testme
402 self.assertCallStack([('__lt__', (1, testme))])
403
404 callLst[:] = []
405 1 != testme
406 self.assertCallStack([('__ne__', (1, testme))])
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000407
408
Thomas Woutersed03b412007-08-28 21:37:11 +0000409 def testGetSetAndDel(self):
410 # Interfering tests
411 class ExtraTests(AllTests):
412 @trackCall
413 def __getattr__(self, *args):
414 return "SomeVal"
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000415
Thomas Woutersed03b412007-08-28 21:37:11 +0000416 @trackCall
417 def __setattr__(self, *args):
418 pass
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000419
Thomas Woutersed03b412007-08-28 21:37:11 +0000420 @trackCall
421 def __delattr__(self, *args):
422 pass
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000423
Thomas Woutersed03b412007-08-28 21:37:11 +0000424 testme = ExtraTests()
425
426 callLst[:] = []
427 testme.spam
428 self.assertCallStack([('__getattr__', (testme, "spam"))])
429
430 callLst[:] = []
431 testme.eggs = "spam, spam, spam and ham"
432 self.assertCallStack([('__setattr__', (testme, "eggs",
433 "spam, spam, spam and ham"))])
434
435 callLst[:] = []
436 del testme.cardinal
437 self.assertCallStack([('__delattr__', (testme, "cardinal"))])
438
439 def testDel(self):
440 x = []
441
442 class DelTest:
443 def __del__(self):
444 x.append("crab people, crab people")
445 testme = DelTest()
446 del testme
447 import gc
448 gc.collect()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000449 self.assertEqual(["crab people, crab people"], x)
Thomas Woutersed03b412007-08-28 21:37:11 +0000450
451 def testBadTypeReturned(self):
452 # return values of some method are type-checked
453 class BadTypeClass:
454 def __int__(self):
455 return None
456 __float__ = __int__
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200457 __complex__ = __int__
Thomas Woutersed03b412007-08-28 21:37:11 +0000458 __str__ = __int__
459 __repr__ = __int__
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200460 __bytes__ = __int__
461 __bool__ = __int__
462 __index__ = __int__
463 def index(x):
464 return [][x]
Thomas Woutersed03b412007-08-28 21:37:11 +0000465
Serhiy Storchakaa60c2fe2015-03-12 21:56:08 +0200466 for f in [float, complex, str, repr, bytes, bin, oct, hex, bool, index]:
Thomas Woutersed03b412007-08-28 21:37:11 +0000467 self.assertRaises(TypeError, f, BadTypeClass())
468
469 def testHashStuff(self):
470 # Test correct errors from hash() on objects with comparisons but
471 # no __hash__
472
473 class C0:
474 pass
475
476 hash(C0()) # This should work; the next two should raise TypeError
477
Thomas Woutersed03b412007-08-28 21:37:11 +0000478 class C2:
479 def __eq__(self, other): return 1
480
481 self.assertRaises(TypeError, hash, C2())
482
483
484 def testSFBug532646(self):
485 # Test for SF bug 532646
486
487 class A:
488 pass
489 A.__call__ = A()
490 a = A()
491
492 try:
493 a() # This should not segfault
494 except RuntimeError:
495 pass
496 else:
497 self.fail("Failed to raise RuntimeError")
498
499 def testForExceptionsRaisedInInstanceGetattr2(self):
500 # Tests for exceptions raised in instance_getattr2().
501
502 def booh(self):
503 raise AttributeError("booh")
504
505 class A:
506 a = property(booh)
507 try:
508 A().a # Raised AttributeError: A instance has no attribute 'a'
509 except AttributeError as x:
510 if str(x) != "booh":
511 self.fail("attribute error for A().a got masked: %s" % x)
512
513 class E:
514 __eq__ = property(booh)
515 E() == E() # In debug mode, caused a C-level assert() to fail
516
517 class I:
518 __init__ = property(booh)
519 try:
520 # In debug mode, printed XXX undetected error and
521 # raises AttributeError
522 I()
523 except AttributeError as x:
524 pass
525 else:
526 self.fail("attribute error for I.__init__ got masked")
527
528 def testHashComparisonOfMethods(self):
529 # Test comparison and hash of methods
530 class A:
531 def __init__(self, x):
532 self.x = x
533 def f(self):
534 pass
535 def g(self):
536 pass
537 def __eq__(self, other):
538 return self.x == other.x
539 def __hash__(self):
540 return self.x
541 class B(A):
542 pass
543
544 a1 = A(1)
545 a2 = A(2)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000546 self.assertEqual(a1.f, a1.f)
547 self.assertNotEqual(a1.f, a2.f)
548 self.assertNotEqual(a1.f, a1.g)
549 self.assertEqual(a1.f, A(1).f)
550 self.assertEqual(hash(a1.f), hash(a1.f))
551 self.assertEqual(hash(a1.f), hash(A(1).f))
Thomas Woutersed03b412007-08-28 21:37:11 +0000552
Ezio Melottib3aedd42010-11-20 19:04:17 +0000553 self.assertNotEqual(A.f, a1.f)
554 self.assertNotEqual(A.f, A.g)
555 self.assertEqual(B.f, A.f)
556 self.assertEqual(hash(B.f), hash(A.f))
Thomas Woutersed03b412007-08-28 21:37:11 +0000557
558 # the following triggers a SystemError in 2.4
Christian Heimes4a22b5d2007-11-25 09:39:14 +0000559 a = A(hash(A.f)^(-1))
Thomas Woutersed03b412007-08-28 21:37:11 +0000560 hash(a.f)
561
562def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000563 support.run_unittest(ClassTests)
Thomas Woutersed03b412007-08-28 21:37:11 +0000564
565if __name__=='__main__':
566 test_main()