blob: 9cf333187a45a3fc33136ab3e97f74eccb616fc9 [file] [log] [blame]
Thomas Wouters1d75a792000-08-17 22:37:32 +00001"Test the functionality of Python classes implementing operators."
2
Georg Brandlc3255562007-08-24 19:33:53 +00003import unittest
4import sys
5
6from test import test_support
Thomas Wouters1d75a792000-08-17 22:37:32 +00007
8testmeths = [
9
10# Binary operations
11 "add",
12 "radd",
13 "sub",
14 "rsub",
15 "mul",
16 "rmul",
17 "div",
18 "rdiv",
19 "mod",
20 "rmod",
21 "divmod",
22 "rdivmod",
23 "pow",
24 "rpow",
25 "rshift",
26 "rrshift",
27 "lshift",
28 "rlshift",
29 "and",
30 "rand",
31 "or",
32 "ror",
33 "xor",
34 "rxor",
35
36# List/dict operations
37 "contains",
38 "getitem",
39 "getslice",
40 "setitem",
41 "setslice",
42 "delitem",
43 "delslice",
44
45# Unary operations
46 "neg",
47 "pos",
48 "abs",
Thomas Wouters1d75a792000-08-17 22:37:32 +000049
50# generic operations
51 "init",
Thomas Wouters1d75a792000-08-17 22:37:32 +000052 ]
53
54# These need to return something other than None
55# "coerce",
56# "hash",
57# "str",
58# "repr",
Neil Schemenauer3a313e32004-07-19 16:29:17 +000059# "int",
60# "long",
61# "float",
62# "oct",
63# "hex",
Thomas Wouters1d75a792000-08-17 22:37:32 +000064
65# These are separate because they can influence the test of other methods.
66# "getattr",
67# "setattr",
68# "delattr",
69
Georg Brandlc3255562007-08-24 19:33:53 +000070callLst = []
71def trackCall(f):
72 def track(*args, **kwargs):
73 callLst.append((f.__name__, args))
74 return f(*args, **kwargs)
75 return track
76
Thomas Wouters1d75a792000-08-17 22:37:32 +000077class AllTests:
Georg Brandlc3255562007-08-24 19:33:53 +000078 trackCall = trackCall
79
80 @trackCall
Thomas Wouters1d75a792000-08-17 22:37:32 +000081 def __coerce__(self, *args):
Fred Drake004d5e62000-10-23 17:22:08 +000082 return (self,) + args
Thomas Wouters1d75a792000-08-17 22:37:32 +000083
Georg Brandlc3255562007-08-24 19:33:53 +000084 @trackCall
Thomas Wouters1d75a792000-08-17 22:37:32 +000085 def __hash__(self, *args):
Trent Mickd68d0a62000-10-04 17:50:59 +000086 return hash(id(self))
Thomas Wouters1d75a792000-08-17 22:37:32 +000087
Georg Brandlc3255562007-08-24 19:33:53 +000088 @trackCall
Thomas Wouters1d75a792000-08-17 22:37:32 +000089 def __str__(self, *args):
Thomas Wouters1d75a792000-08-17 22:37:32 +000090 return "AllTests"
91
Georg Brandlc3255562007-08-24 19:33:53 +000092 @trackCall
Thomas Wouters1d75a792000-08-17 22:37:32 +000093 def __repr__(self, *args):
Thomas Wouters1d75a792000-08-17 22:37:32 +000094 return "AllTests"
95
Georg Brandlc3255562007-08-24 19:33:53 +000096 @trackCall
Neil Schemenauer3a313e32004-07-19 16:29:17 +000097 def __int__(self, *args):
Neil Schemenauer3a313e32004-07-19 16:29:17 +000098 return 1
99
Georg Brandlc3255562007-08-24 19:33:53 +0000100 @trackCall
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000101 def __float__(self, *args):
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000102 return 1.0
103
Georg Brandlc3255562007-08-24 19:33:53 +0000104 @trackCall
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000105 def __long__(self, *args):
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000106 return 1L
107
Georg Brandlc3255562007-08-24 19:33:53 +0000108 @trackCall
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000109 def __oct__(self, *args):
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000110 return '01'
111
Georg Brandlc3255562007-08-24 19:33:53 +0000112 @trackCall
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000113 def __hex__(self, *args):
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000114 return '0x1'
115
Georg Brandlc3255562007-08-24 19:33:53 +0000116 @trackCall
Thomas Wouters1d75a792000-08-17 22:37:32 +0000117 def __cmp__(self, *args):
Thomas Wouters1d75a792000-08-17 22:37:32 +0000118 return 0
119
Georg Brandlc3255562007-08-24 19:33:53 +0000120# Synthesize all the other AllTests methods from the names in testmeths.
Tim Peters01705212001-12-11 19:28:47 +0000121
122method_template = """\
Georg Brandlc3255562007-08-24 19:33:53 +0000123@trackCall
Tim Peters01705212001-12-11 19:28:47 +0000124def __%(method)s__(self, *args):
Georg Brandlc3255562007-08-24 19:33:53 +0000125 pass
Tim Peters01705212001-12-11 19:28:47 +0000126"""
127
Thomas Wouters1d75a792000-08-17 22:37:32 +0000128for method in testmeths:
Tim Peters01705212001-12-11 19:28:47 +0000129 exec method_template % locals() in AllTests.__dict__
130
131del method, method_template
Thomas Wouters1d75a792000-08-17 22:37:32 +0000132
Georg Brandlc3255562007-08-24 19:33:53 +0000133class ClassTests(unittest.TestCase):
134 def setUp(self):
135 callLst[:] = []
Thomas Wouters1d75a792000-08-17 22:37:32 +0000136
Georg Brandlc3255562007-08-24 19:33:53 +0000137 def assertCallStack(self, expected_calls):
138 actualCallList = callLst[:] # need to copy because the comparison below will add
139 # additional calls to callLst
140 if expected_calls != actualCallList:
141 self.fail("Expected call list:\n %s\ndoes not match actual call list\n %s" %
142 (expected_calls, actualCallList))
Thomas Wouters1d75a792000-08-17 22:37:32 +0000143
Georg Brandlc3255562007-08-24 19:33:53 +0000144 def testInit(self):
145 foo = AllTests()
146 self.assertCallStack([("__init__", (foo,))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000147
Georg Brandlc3255562007-08-24 19:33:53 +0000148 def testBinaryOps(self):
149 testme = AllTests()
150 # Binary operations
Thomas Wouters1d75a792000-08-17 22:37:32 +0000151
Georg Brandlc3255562007-08-24 19:33:53 +0000152 callLst[:] = []
153 testme + 1
154 self.assertCallStack([("__coerce__", (testme, 1)), ("__add__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000155
Georg Brandlc3255562007-08-24 19:33:53 +0000156 callLst[:] = []
157 1 + testme
158 self.assertCallStack([("__coerce__", (testme, 1)), ("__radd__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000159
Georg Brandlc3255562007-08-24 19:33:53 +0000160 callLst[:] = []
161 testme - 1
162 self.assertCallStack([("__coerce__", (testme, 1)), ("__sub__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000163
Georg Brandlc3255562007-08-24 19:33:53 +0000164 callLst[:] = []
165 1 - testme
166 self.assertCallStack([("__coerce__", (testme, 1)), ("__rsub__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000167
Georg Brandlc3255562007-08-24 19:33:53 +0000168 callLst[:] = []
169 testme * 1
170 self.assertCallStack([("__coerce__", (testme, 1)), ("__mul__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000171
Georg Brandlc3255562007-08-24 19:33:53 +0000172 callLst[:] = []
173 1 * testme
174 self.assertCallStack([("__coerce__", (testme, 1)), ("__rmul__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000175
Georg Brandlc3255562007-08-24 19:33:53 +0000176 if 1/2 == 0:
177 callLst[:] = []
178 testme / 1
179 self.assertCallStack([("__coerce__", (testme, 1)), ("__div__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000180
Thomas Wouters1d75a792000-08-17 22:37:32 +0000181
Georg Brandlc3255562007-08-24 19:33:53 +0000182 callLst[:] = []
183 1 / testme
184 self.assertCallStack([("__coerce__", (testme, 1)), ("__rdiv__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000185
Georg Brandlc3255562007-08-24 19:33:53 +0000186 callLst[:] = []
187 testme % 1
188 self.assertCallStack([("__coerce__", (testme, 1)), ("__mod__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000189
Georg Brandlc3255562007-08-24 19:33:53 +0000190 callLst[:] = []
191 1 % testme
192 self.assertCallStack([("__coerce__", (testme, 1)), ("__rmod__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000193
Thomas Wouters1d75a792000-08-17 22:37:32 +0000194
Georg Brandlc3255562007-08-24 19:33:53 +0000195 callLst[:] = []
196 divmod(testme,1)
197 self.assertCallStack([("__coerce__", (testme, 1)), ("__divmod__", (testme, 1))])
Martin v. Löwis3a624042006-11-08 06:46:37 +0000198
Georg Brandlc3255562007-08-24 19:33:53 +0000199 callLst[:] = []
200 divmod(1, testme)
201 self.assertCallStack([("__coerce__", (testme, 1)), ("__rdivmod__", (testme, 1))])
Martin v. Löwis3a624042006-11-08 06:46:37 +0000202
Georg Brandlc3255562007-08-24 19:33:53 +0000203 callLst[:] = []
204 testme ** 1
205 self.assertCallStack([("__coerce__", (testme, 1)), ("__pow__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000206
Georg Brandlc3255562007-08-24 19:33:53 +0000207 callLst[:] = []
208 1 ** testme
209 self.assertCallStack([("__coerce__", (testme, 1)), ("__rpow__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000210
Georg Brandlc3255562007-08-24 19:33:53 +0000211 callLst[:] = []
212 testme >> 1
213 self.assertCallStack([("__coerce__", (testme, 1)), ("__rshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000214
Georg Brandlc3255562007-08-24 19:33:53 +0000215 callLst[:] = []
216 1 >> testme
217 self.assertCallStack([("__coerce__", (testme, 1)), ("__rrshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000218
Georg Brandlc3255562007-08-24 19:33:53 +0000219 callLst[:] = []
220 testme << 1
221 self.assertCallStack([("__coerce__", (testme, 1)), ("__lshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000222
Georg Brandlc3255562007-08-24 19:33:53 +0000223 callLst[:] = []
224 1 << testme
225 self.assertCallStack([("__coerce__", (testme, 1)), ("__rlshift__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000226
Georg Brandlc3255562007-08-24 19:33:53 +0000227 callLst[:] = []
228 testme & 1
229 self.assertCallStack([("__coerce__", (testme, 1)), ("__and__", (testme, 1))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000230
Georg Brandlc3255562007-08-24 19:33:53 +0000231 callLst[:] = []
232 1 & testme
233 self.assertCallStack([("__coerce__", (testme, 1)), ("__rand__", (testme, 1))])
234
235 callLst[:] = []
236 testme | 1
237 self.assertCallStack([("__coerce__", (testme, 1)), ("__or__", (testme, 1))])
238
239 callLst[:] = []
240 1 | testme
241 self.assertCallStack([("__coerce__", (testme, 1)), ("__ror__", (testme, 1))])
242
243 callLst[:] = []
244 testme ^ 1
245 self.assertCallStack([("__coerce__", (testme, 1)), ("__xor__", (testme, 1))])
246
247 callLst[:] = []
248 1 ^ testme
249 self.assertCallStack([("__coerce__", (testme, 1)), ("__rxor__", (testme, 1))])
250
251 def testListAndDictOps(self):
252 testme = AllTests()
253
254 # List/dict operations
255
256 class Empty: pass
257
258 try:
259 1 in Empty()
260 self.fail('failed, should have raised TypeError')
261 except TypeError:
262 pass
263
264 callLst[:] = []
265 1 in testme
266 self.assertCallStack([('__contains__', (testme, 1))])
267
268 callLst[:] = []
269 testme[1]
270 self.assertCallStack([('__getitem__', (testme, 1))])
271
272 callLst[:] = []
273 testme[1] = 1
274 self.assertCallStack([('__setitem__', (testme, 1, 1))])
275
276 callLst[:] = []
277 del testme[1]
278 self.assertCallStack([('__delitem__', (testme, 1))])
279
280 callLst[:] = []
281 testme[:42]
282 self.assertCallStack([('__getslice__', (testme, 0, 42))])
283
284 callLst[:] = []
285 testme[:42] = "The Answer"
286 self.assertCallStack([('__setslice__', (testme, 0, 42, "The Answer"))])
287
288 callLst[:] = []
289 del testme[:42]
290 self.assertCallStack([('__delslice__', (testme, 0, 42))])
291
292 callLst[:] = []
293 testme[2:1024:10]
294 self.assertCallStack([('__getitem__', (testme, slice(2, 1024, 10)))])
295
296 callLst[:] = []
297 testme[2:1024:10] = "A lot"
298 self.assertCallStack([('__setitem__', (testme, slice(2, 1024, 10),
299 "A lot"))])
300 callLst[:] = []
301 del testme[2:1024:10]
302 self.assertCallStack([('__delitem__', (testme, slice(2, 1024, 10)))])
303
304 callLst[:] = []
305 testme[:42, ..., :24:, 24, 100]
306 self.assertCallStack([('__getitem__', (testme, (slice(None, 42, None),
307 Ellipsis,
308 slice(None, 24, None),
309 24, 100)))])
310 callLst[:] = []
311 testme[:42, ..., :24:, 24, 100] = "Strange"
312 self.assertCallStack([('__setitem__', (testme, (slice(None, 42, None),
313 Ellipsis,
314 slice(None, 24, None),
315 24, 100), "Strange"))])
316 callLst[:] = []
317 del testme[:42, ..., :24:, 24, 100]
318 self.assertCallStack([('__delitem__', (testme, (slice(None, 42, None),
319 Ellipsis,
320 slice(None, 24, None),
321 24, 100)))])
322
323 # Now remove the slice hooks to see if converting normal slices to
324 # slice object works.
325
326 getslice = AllTests.__getslice__
327 del AllTests.__getslice__
328 setslice = AllTests.__setslice__
329 del AllTests.__setslice__
330 delslice = AllTests.__delslice__
331 del AllTests.__delslice__
332
333 # XXX when using new-style classes the slice testme[:42] produces
334 # slice(None, 42, None) instead of slice(0, 42, None). py3k will have
335 # to change this test.
336 callLst[:] = []
337 testme[:42]
338 self.assertCallStack([('__getitem__', (testme, slice(0, 42, None)))])
339
340 callLst[:] = []
341 testme[:42] = "The Answer"
342 self.assertCallStack([('__setitem__', (testme, slice(0, 42, None),
343 "The Answer"))])
344 callLst[:] = []
345 del testme[:42]
346 self.assertCallStack([('__delitem__', (testme, slice(0, 42, None)))])
347
348 # Restore the slice methods, or the tests will fail with regrtest -R.
349 AllTests.__getslice__ = getslice
350 AllTests.__setslice__ = setslice
351 AllTests.__delslice__ = delslice
352
353
354 def testUnaryOps(self):
355 testme = AllTests()
356
357 callLst[:] = []
358 -testme
359 self.assertCallStack([('__neg__', (testme,))])
360 callLst[:] = []
361 +testme
362 self.assertCallStack([('__pos__', (testme,))])
363 callLst[:] = []
364 abs(testme)
365 self.assertCallStack([('__abs__', (testme,))])
366 callLst[:] = []
367 int(testme)
368 self.assertCallStack([('__int__', (testme,))])
369 callLst[:] = []
370 long(testme)
371 self.assertCallStack([('__long__', (testme,))])
372 callLst[:] = []
373 float(testme)
374 self.assertCallStack([('__float__', (testme,))])
375 callLst[:] = []
376 oct(testme)
377 self.assertCallStack([('__oct__', (testme,))])
378 callLst[:] = []
379 hex(testme)
380 self.assertCallStack([('__hex__', (testme,))])
381
382
383 def testMisc(self):
384 testme = AllTests()
385
386 callLst[:] = []
387 hash(testme)
388 self.assertCallStack([('__hash__', (testme,))])
389
390 callLst[:] = []
391 repr(testme)
392 self.assertCallStack([('__repr__', (testme,))])
393
394 callLst[:] = []
395 str(testme)
396 self.assertCallStack([('__str__', (testme,))])
397
398 callLst[:] = []
399 testme == 1
400 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
401
402 callLst[:] = []
403 testme < 1
404 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
405
406 callLst[:] = []
407 testme > 1
408 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
409
410 callLst[:] = []
411 testme <> 1 # XXX kill this in py3k
412 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
413
414 callLst[:] = []
415 testme != 1
416 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (testme, 1))])
417
418 callLst[:] = []
419 1 == testme
420 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
421
422 callLst[:] = []
423 1 < testme
424 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000425
Georg Brandlc3255562007-08-24 19:33:53 +0000426 callLst[:] = []
427 1 > testme
428 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000429
Georg Brandlc3255562007-08-24 19:33:53 +0000430 callLst[:] = []
431 1 <> testme
432 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000433
Georg Brandlc3255562007-08-24 19:33:53 +0000434 callLst[:] = []
435 1 != testme
436 self.assertCallStack([("__coerce__", (testme, 1)), ('__cmp__', (1, testme))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000437
Thomas Wouters1d75a792000-08-17 22:37:32 +0000438
Georg Brandlc3255562007-08-24 19:33:53 +0000439 def testGetSetAndDel(self):
440 # Interfering tests
441 class ExtraTests(AllTests):
442 @trackCall
443 def __getattr__(self, *args):
444 return "SomeVal"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000445
Georg Brandlc3255562007-08-24 19:33:53 +0000446 @trackCall
447 def __setattr__(self, *args):
448 pass
Thomas Wouters1d75a792000-08-17 22:37:32 +0000449
Georg Brandlc3255562007-08-24 19:33:53 +0000450 @trackCall
451 def __delattr__(self, *args):
452 pass
Thomas Wouters1d75a792000-08-17 22:37:32 +0000453
Georg Brandlc3255562007-08-24 19:33:53 +0000454 testme = ExtraTests()
Thomas Wouters1d75a792000-08-17 22:37:32 +0000455
Georg Brandlc3255562007-08-24 19:33:53 +0000456 callLst[:] = []
457 testme.spam
458 self.assertCallStack([('__getattr__', (testme, "spam"))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000459
Georg Brandlc3255562007-08-24 19:33:53 +0000460 callLst[:] = []
461 testme.eggs = "spam, spam, spam and ham"
462 self.assertCallStack([('__setattr__', (testme, "eggs",
463 "spam, spam, spam and ham"))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000464
Georg Brandlc3255562007-08-24 19:33:53 +0000465 callLst[:] = []
466 del testme.cardinal
467 self.assertCallStack([('__delattr__', (testme, "cardinal"))])
Thomas Wouters1d75a792000-08-17 22:37:32 +0000468
Georg Brandlc3255562007-08-24 19:33:53 +0000469 def testDel(self):
470 x = []
Thomas Wouters1d75a792000-08-17 22:37:32 +0000471
Georg Brandlc3255562007-08-24 19:33:53 +0000472 class DelTest:
473 def __del__(self):
474 x.append("crab people, crab people")
475 testme = DelTest()
476 del testme
477 import gc
478 gc.collect()
479 self.assertEquals(["crab people, crab people"], x)
Guido van Rossum23120242001-01-18 23:47:15 +0000480
Georg Brandlc3255562007-08-24 19:33:53 +0000481 def testBadTypeReturned(self):
482 # return values of some method are type-checked
483 class BadTypeClass:
484 def __int__(self):
485 return None
486 __float__ = __int__
487 __long__ = __int__
488 __str__ = __int__
489 __repr__ = __int__
490 __oct__ = __int__
491 __hex__ = __int__
Guido van Rossum23120242001-01-18 23:47:15 +0000492
Georg Brandlc3255562007-08-24 19:33:53 +0000493 for f in [int, float, long, str, repr, oct, hex]:
494 self.assertRaises(TypeError, f, BadTypeClass())
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000495
Georg Brandlc3255562007-08-24 19:33:53 +0000496 def testMixIntsAndLongs(self):
497 # mixing up ints and longs is okay
498 class IntLongMixClass:
499 @trackCall
500 def __int__(self):
501 return 42L
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000502
Georg Brandlc3255562007-08-24 19:33:53 +0000503 @trackCall
504 def __long__(self):
505 return 64
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000506
Georg Brandlc3255562007-08-24 19:33:53 +0000507 mixIntAndLong = IntLongMixClass()
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000508
Georg Brandlc3255562007-08-24 19:33:53 +0000509 callLst[:] = []
510 as_int = int(mixIntAndLong)
511 self.assertEquals(type(as_int), long)
512 self.assertEquals(as_int, 42L)
513 self.assertCallStack([('__int__', (mixIntAndLong,))])
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000514
Georg Brandlc3255562007-08-24 19:33:53 +0000515 callLst[:] = []
516 as_long = long(mixIntAndLong)
517 self.assertEquals(type(as_long), int)
518 self.assertEquals(as_long, 64)
519 self.assertCallStack([('__long__', (mixIntAndLong,))])
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000520
Georg Brandlc3255562007-08-24 19:33:53 +0000521 def testHashStuff(self):
522 # Test correct errors from hash() on objects with comparisons but
523 # no __hash__
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000524
Georg Brandlc3255562007-08-24 19:33:53 +0000525 class C0:
526 pass
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000527
Georg Brandlc3255562007-08-24 19:33:53 +0000528 hash(C0()) # This should work; the next two should raise TypeError
Guido van Rossum23120242001-01-18 23:47:15 +0000529
Georg Brandlc3255562007-08-24 19:33:53 +0000530 class C1:
531 def __cmp__(self, other): return 0
Guido van Rossum23120242001-01-18 23:47:15 +0000532
Georg Brandlc3255562007-08-24 19:33:53 +0000533 self.assertRaises(TypeError, hash, C1())
Guido van Rossum23120242001-01-18 23:47:15 +0000534
Georg Brandlc3255562007-08-24 19:33:53 +0000535 class C2:
536 def __eq__(self, other): return 1
Guido van Rossum23120242001-01-18 23:47:15 +0000537
Georg Brandlc3255562007-08-24 19:33:53 +0000538 self.assertRaises(TypeError, hash, C2())
Guido van Rossum23120242001-01-18 23:47:15 +0000539
Guido van Rossum23120242001-01-18 23:47:15 +0000540
Georg Brandlc3255562007-08-24 19:33:53 +0000541 def testSFBug532646(self):
542 # Test for SF bug 532646
Guido van Rossum16b93b32002-06-13 21:32:51 +0000543
Georg Brandlc3255562007-08-24 19:33:53 +0000544 class A:
545 pass
546 A.__call__ = A()
547 a = A()
Guido van Rossum16b93b32002-06-13 21:32:51 +0000548
Georg Brandlc3255562007-08-24 19:33:53 +0000549 try:
550 a() # This should not segfault
551 except RuntimeError:
552 pass
553 else:
554 self.fail("Failed to raise RuntimeError")
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000555
Georg Brandlc3255562007-08-24 19:33:53 +0000556 def testForExceptionsRaisedInInstanceGetattr2(self):
557 # Tests for exceptions raised in instance_getattr2().
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000558
Georg Brandlc3255562007-08-24 19:33:53 +0000559 def booh(self):
560 raise AttributeError("booh")
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000561
Georg Brandlc3255562007-08-24 19:33:53 +0000562 class A:
563 a = property(booh)
564 try:
565 A().a # Raised AttributeError: A instance has no attribute 'a'
566 except AttributeError, x:
567 if str(x) != "booh":
568 self.fail("attribute error for A().a got masked: %s" % x)
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000569
Georg Brandlc3255562007-08-24 19:33:53 +0000570 class E:
571 __eq__ = property(booh)
572 E() == E() # In debug mode, caused a C-level assert() to fail
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000573
Georg Brandlc3255562007-08-24 19:33:53 +0000574 class I:
575 __init__ = property(booh)
576 try:
577 # In debug mode, printed XXX undetected error and
578 # raises AttributeError
579 I()
580 except AttributeError, x:
581 pass
582 else:
583 self.fail("attribute error for I.__init__ got masked")
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000584
Georg Brandlc3255562007-08-24 19:33:53 +0000585 def testHashComparisonOfMethods(self):
586 # Test comparison and hash of methods
587 class A:
588 def __init__(self, x):
589 self.x = x
590 def f(self):
591 pass
592 def g(self):
593 pass
594 def __eq__(self, other):
595 return self.x == other.x
596 def __hash__(self):
597 return self.x
598 class B(A):
599 pass
Armin Rigofd01d792006-06-08 10:56:24 +0000600
Georg Brandlc3255562007-08-24 19:33:53 +0000601 a1 = A(1)
602 a2 = A(2)
603 self.assertEquals(a1.f, a1.f)
604 self.assertNotEquals(a1.f, a2.f)
605 self.assertNotEquals(a1.f, a1.g)
606 self.assertEquals(a1.f, A(1).f)
607 self.assertEquals(hash(a1.f), hash(a1.f))
608 self.assertEquals(hash(a1.f), hash(A(1).f))
Armin Rigofd01d792006-06-08 10:56:24 +0000609
Georg Brandlc3255562007-08-24 19:33:53 +0000610 self.assertNotEquals(A.f, a1.f)
611 self.assertNotEquals(A.f, A.g)
612 self.assertEquals(B.f, A.f)
613 self.assertEquals(hash(B.f), hash(A.f))
Armin Rigofd01d792006-06-08 10:56:24 +0000614
Georg Brandlc3255562007-08-24 19:33:53 +0000615 # the following triggers a SystemError in 2.4
616 a = A(hash(A.f.im_func)^(-1))
617 hash(a.f)
Armin Rigofd01d792006-06-08 10:56:24 +0000618
Georg Brandlc3255562007-08-24 19:33:53 +0000619def test_main():
620 test_support.run_unittest(ClassTests)
Armin Rigofd01d792006-06-08 10:56:24 +0000621
Georg Brandlc3255562007-08-24 19:33:53 +0000622if __name__=='__main__':
623 test_main()