blob: 3201dd8c5d1e2ccbbdd69162ff6cd3fef87dd699 [file] [log] [blame]
Thomas Wouters1d75a792000-08-17 22:37:32 +00001"Test the functionality of Python classes implementing operators."
2
Barry Warsaw408b6d32002-07-30 23:27:12 +00003from test.test_support import TestFailed
Thomas Wouters1d75a792000-08-17 22:37:32 +00004
5testmeths = [
6
7# Binary operations
8 "add",
9 "radd",
10 "sub",
11 "rsub",
12 "mul",
13 "rmul",
Neal Norwitzbcc0db82006-03-24 08:14:36 +000014 "truediv",
15 "rtruediv",
Thomas Wouters1d75a792000-08-17 22:37:32 +000016 "mod",
17 "rmod",
18 "divmod",
19 "rdivmod",
20 "pow",
21 "rpow",
22 "rshift",
23 "rrshift",
24 "lshift",
25 "rlshift",
26 "and",
27 "rand",
28 "or",
29 "ror",
30 "xor",
31 "rxor",
32
33# List/dict operations
34 "contains",
35 "getitem",
36 "getslice",
37 "setitem",
38 "setslice",
39 "delitem",
40 "delslice",
41
42# Unary operations
43 "neg",
44 "pos",
45 "abs",
Thomas Wouters1d75a792000-08-17 22:37:32 +000046
47# generic operations
48 "init",
Thomas Wouters1d75a792000-08-17 22:37:32 +000049 ]
50
51# These need to return something other than None
Thomas Wouters1d75a792000-08-17 22:37:32 +000052# "hash",
53# "str",
54# "repr",
Neil Schemenauer3a313e32004-07-19 16:29:17 +000055# "int",
56# "long",
57# "float",
58# "oct",
59# "hex",
Thomas Wouters1d75a792000-08-17 22:37:32 +000060
61# These are separate because they can influence the test of other methods.
62# "getattr",
63# "setattr",
64# "delattr",
65
66class AllTests:
Thomas Wouters1d75a792000-08-17 22:37:32 +000067 def __hash__(self, *args):
68 print "__hash__:", args
Trent Mickd68d0a62000-10-04 17:50:59 +000069 return hash(id(self))
Thomas Wouters1d75a792000-08-17 22:37:32 +000070
71 def __str__(self, *args):
72 print "__str__:", args
73 return "AllTests"
74
75 def __repr__(self, *args):
76 print "__repr__:", args
77 return "AllTests"
78
Neil Schemenauer3a313e32004-07-19 16:29:17 +000079 def __int__(self, *args):
80 print "__int__:", args
81 return 1
82
83 def __float__(self, *args):
84 print "__float__:", args
85 return 1.0
86
87 def __long__(self, *args):
88 print "__long__:", args
89 return 1L
90
91 def __oct__(self, *args):
92 print "__oct__:", args
93 return '01'
94
95 def __hex__(self, *args):
96 print "__hex__:", args
97 return '0x1'
98
Thomas Wouters1d75a792000-08-17 22:37:32 +000099 def __cmp__(self, *args):
100 print "__cmp__:", args
101 return 0
102
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000103 def __eq__(self, *args):
104 print "__eq__:", args
105 return True
106
107 def __ne__(self, *args):
108 print "__ne__:", args
109 return False
110
111 def __lt__(self, *args):
112 print "__lt__:", args
113 return False
114
115 def __le__(self, *args):
116 print "__le__:", args
117 return True
118
119 def __gt__(self, *args):
120 print "__gt__:", args
121 return False
122
123 def __ge__(self, *args):
124 print "__ge__:", args
125 return True
126
Barry Warsaw07d8d642001-08-20 20:29:07 +0000127 def __del__(self, *args):
128 print "__del__:", args
129
Tim Peters01705212001-12-11 19:28:47 +0000130# Synthesize AllTests methods from the names in testmeths.
131
132method_template = """\
133def __%(method)s__(self, *args):
134 print "__%(method)s__:", args
135"""
136
Thomas Wouters4cdada92006-04-15 09:19:16 +0000137d = {}
Thomas Wouters1d75a792000-08-17 22:37:32 +0000138for method in testmeths:
Georg Brandl7cae87c2006-09-06 06:51:57 +0000139 exec(method_template % locals(), d)
Thomas Wouters4cdada92006-04-15 09:19:16 +0000140for k in d:
141 setattr(AllTests, k, d[k])
142del d, k
Tim Peters01705212001-12-11 19:28:47 +0000143del method, method_template
Thomas Wouters1d75a792000-08-17 22:37:32 +0000144
145# this also tests __init__ of course.
146testme = AllTests()
147
148# Binary operations
149
150testme + 1
1511 + testme
152
153testme - 1
1541 - testme
155
156testme * 1
1571 * testme
158
Neal Norwitzbcc0db82006-03-24 08:14:36 +0000159testme / 1
1601 / testme
Thomas Wouters1d75a792000-08-17 22:37:32 +0000161
162testme % 1
1631 % testme
164
165divmod(testme,1)
166divmod(1, testme)
167
168testme ** 1
1691 ** testme
170
171testme >> 1
1721 >> testme
173
174testme << 1
1751 << testme
176
177testme & 1
1781 & testme
179
180testme | 1
1811 | testme
182
183testme ^ 1
1841 ^ testme
185
186
187# List/dict operations
188
Thomas Wouters89f507f2006-12-13 04:49:30 +0000189class Empty: pass
190
191try:
192 1 in Empty()
193 print 'failed, should have raised TypeError'
194except TypeError:
195 pass
196
Thomas Wouters1d75a792000-08-17 22:37:32 +00001971 in testme
198
199testme[1]
200testme[1] = 1
201del testme[1]
202
203testme[:42]
204testme[:42] = "The Answer"
205del testme[:42]
206
207testme[2:1024:10]
208testme[2:1024:10] = "A lot"
209del testme[2:1024:10]
210
211testme[:42, ..., :24:, 24, 100]
212testme[:42, ..., :24:, 24, 100] = "Strange"
213del testme[:42, ..., :24:, 24, 100]
214
215
216# Now remove the slice hooks to see if converting normal slices to slice
217# object works.
218
219del AllTests.__getslice__
220del AllTests.__setslice__
221del AllTests.__delslice__
222
Barry Warsaw07d8d642001-08-20 20:29:07 +0000223import sys
224if sys.platform[:4] != 'java':
225 testme[:42]
226 testme[:42] = "The Answer"
227 del testme[:42]
228else:
229 # This works under Jython, but the actual slice values are
230 # different.
231 print "__getitem__: (slice(0, 42, None),)"
232 print "__setitem__: (slice(0, 42, None), 'The Answer')"
233 print "__delitem__: (slice(0, 42, None),)"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000234
235# Unary operations
236
237-testme
238+testme
239abs(testme)
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000240int(testme)
241long(testme)
242float(testme)
243oct(testme)
244hex(testme)
Thomas Wouters1d75a792000-08-17 22:37:32 +0000245
246# And the rest...
247
248hash(testme)
249repr(testme)
250str(testme)
251
252testme == 1
253testme < 1
254testme > 1
Thomas Wouters1d75a792000-08-17 22:37:32 +0000255testme != 1
2561 == testme
2571 < testme
2581 > testme
Thomas Wouters1d75a792000-08-17 22:37:32 +00002591 != testme
260
261# This test has to be last (duh.)
262
263del testme
Barry Warsaw07d8d642001-08-20 20:29:07 +0000264if sys.platform[:4] == 'java':
265 import java
266 java.lang.System.gc()
Thomas Wouters1d75a792000-08-17 22:37:32 +0000267
268# Interfering tests
269
270class ExtraTests:
Fred Drake004d5e62000-10-23 17:22:08 +0000271 def __getattr__(self, *args):
272 print "__getattr__:", args
273 return "SomeVal"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000274
Fred Drake004d5e62000-10-23 17:22:08 +0000275 def __setattr__(self, *args):
276 print "__setattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000277
Fred Drake004d5e62000-10-23 17:22:08 +0000278 def __delattr__(self, *args):
279 print "__delattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000280
281testme = ExtraTests()
282testme.spam
283testme.eggs = "spam, spam, spam and ham"
284del testme.cardinal
Guido van Rossum23120242001-01-18 23:47:15 +0000285
286
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000287# return values of some method are type-checked
288class BadTypeClass:
289 def __int__(self):
290 return None
291 __float__ = __int__
292 __long__ = __int__
293 __str__ = __int__
294 __repr__ = __int__
295 __oct__ = __int__
296 __hex__ = __int__
297
298def check_exc(stmt, exception):
299 """Raise TestFailed if executing 'stmt' does not raise 'exception'
300 """
301 try:
Georg Brandl7cae87c2006-09-06 06:51:57 +0000302 exec(stmt)
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000303 except exception:
304 pass
305 else:
306 raise TestFailed, "%s should raise %s" % (stmt, exception)
307
308check_exc("int(BadTypeClass())", TypeError)
309check_exc("float(BadTypeClass())", TypeError)
310check_exc("long(BadTypeClass())", TypeError)
311check_exc("str(BadTypeClass())", TypeError)
312check_exc("repr(BadTypeClass())", TypeError)
313check_exc("oct(BadTypeClass())", TypeError)
314check_exc("hex(BadTypeClass())", TypeError)
315
316# mixing up ints and longs is okay
317class IntLongMixClass:
318 def __int__(self):
319 return 0L
320
321 def __long__(self):
322 return 0
323
324try:
325 int(IntLongMixClass())
326except TypeError:
327 raise TestFailed, "TypeError should not be raised"
328
329try:
330 long(IntLongMixClass())
331except TypeError:
332 raise TestFailed, "TypeError should not be raised"
333
334
Guido van Rossum23120242001-01-18 23:47:15 +0000335# Test correct errors from hash() on objects with comparisons but no __hash__
336
337class C0:
338 pass
339
340hash(C0()) # This should work; the next two should raise TypeError
341
342class C1:
343 def __cmp__(self, other): return 0
344
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000345check_exc("hash(C1())", TypeError)
Guido van Rossum23120242001-01-18 23:47:15 +0000346
347class C2:
348 def __eq__(self, other): return 1
349
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000350check_exc("hash(C2())", TypeError)
Guido van Rossum16b93b32002-06-13 21:32:51 +0000351
352# Test for SF bug 532646
353
354class A:
355 pass
356A.__call__ = A()
357a = A()
358try:
359 a() # This should not segfault
360except RuntimeError:
361 pass
362else:
363 raise TestFailed, "how could this not have overflowed the stack?"
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000364
365
366# Tests for exceptions raised in instance_getattr2().
367
368def booh(self):
369 raise AttributeError, "booh"
370
371class A:
372 a = property(booh)
373try:
374 A().a # Raised AttributeError: A instance has no attribute 'a'
375except AttributeError, x:
Michael W. Hudsonabb103b2005-05-04 11:59:38 +0000376 if str(x) != "booh":
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000377 print "attribute error for A().a got masked:", str(x)
378
379class E:
380 __eq__ = property(booh)
381E() == E() # In debug mode, caused a C-level assert() to fail
382
383class I:
384 __init__ = property(booh)
385try:
386 I() # In debug mode, printed XXX undetected error and raises AttributeError
387except AttributeError, x:
388 pass
389else:
390 print "attribute error for I.__init__ got masked"
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000391
392
393# Test comparison and hash of methods
394class A:
395 def __init__(self, x):
396 self.x = x
397 def f(self):
398 pass
399 def g(self):
400 pass
401 def __eq__(self, other):
402 return self.x == other.x
403 def __hash__(self):
404 return self.x
405class B(A):
406 pass
407
408a1 = A(1)
409a2 = A(2)
410assert a1.f == a1.f
411assert a1.f != a2.f
412assert a1.f != a1.g
413assert a1.f == A(1).f
414assert hash(a1.f) == hash(a1.f)
415assert hash(a1.f) == hash(A(1).f)
416
417assert A.f != a1.f
418assert A.f != A.g
419assert B.f == A.f
420assert hash(B.f) == hash(A.f)
421
422# the following triggers a SystemError in 2.4
423a = A(hash(A.f.im_func)^(-1))
424hash(a.f)