blob: 26b8e7a134f53affbebd5e1c1cafd4deb9f7ad18 [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",
14 "div",
15 "rdiv",
16 "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
52# "coerce",
53# "hash",
54# "str",
55# "repr",
Neil Schemenauer3a313e32004-07-19 16:29:17 +000056# "int",
57# "long",
58# "float",
59# "oct",
60# "hex",
Thomas Wouters1d75a792000-08-17 22:37:32 +000061
62# These are separate because they can influence the test of other methods.
63# "getattr",
64# "setattr",
65# "delattr",
66
67class AllTests:
68 def __coerce__(self, *args):
69 print "__coerce__:", args
Fred Drake004d5e62000-10-23 17:22:08 +000070 return (self,) + args
Thomas Wouters1d75a792000-08-17 22:37:32 +000071
72 def __hash__(self, *args):
73 print "__hash__:", args
Trent Mickd68d0a62000-10-04 17:50:59 +000074 return hash(id(self))
Thomas Wouters1d75a792000-08-17 22:37:32 +000075
76 def __str__(self, *args):
77 print "__str__:", args
78 return "AllTests"
79
80 def __repr__(self, *args):
81 print "__repr__:", args
82 return "AllTests"
83
Neil Schemenauer3a313e32004-07-19 16:29:17 +000084 def __int__(self, *args):
85 print "__int__:", args
86 return 1
87
88 def __float__(self, *args):
89 print "__float__:", args
90 return 1.0
91
92 def __long__(self, *args):
93 print "__long__:", args
94 return 1L
95
96 def __oct__(self, *args):
97 print "__oct__:", args
98 return '01'
99
100 def __hex__(self, *args):
101 print "__hex__:", args
102 return '0x1'
103
Thomas Wouters1d75a792000-08-17 22:37:32 +0000104 def __cmp__(self, *args):
105 print "__cmp__:", args
106 return 0
107
Barry Warsaw07d8d642001-08-20 20:29:07 +0000108 def __del__(self, *args):
109 print "__del__:", args
110
Tim Peters01705212001-12-11 19:28:47 +0000111# Synthesize AllTests methods from the names in testmeths.
112
113method_template = """\
114def __%(method)s__(self, *args):
115 print "__%(method)s__:", args
116"""
117
Thomas Wouters1d75a792000-08-17 22:37:32 +0000118for method in testmeths:
Tim Peters01705212001-12-11 19:28:47 +0000119 exec method_template % locals() in AllTests.__dict__
120
121del method, method_template
Thomas Wouters1d75a792000-08-17 22:37:32 +0000122
123# this also tests __init__ of course.
124testme = AllTests()
125
126# Binary operations
127
128testme + 1
1291 + testme
130
131testme - 1
1321 - testme
133
134testme * 1
1351 * testme
136
Tim Peters01705212001-12-11 19:28:47 +0000137if 1/2 == 0:
138 testme / 1
139 1 / testme
140else:
141 # True division is in effect, so "/" doesn't map to __div__ etc; but
142 # the canned expected-output file requires that __div__ etc get called.
143 testme.__coerce__(1)
144 testme.__div__(1)
145 testme.__coerce__(1)
146 testme.__rdiv__(1)
Thomas Wouters1d75a792000-08-17 22:37:32 +0000147
148testme % 1
1491 % testme
150
151divmod(testme,1)
152divmod(1, testme)
153
154testme ** 1
1551 ** testme
156
157testme >> 1
1581 >> testme
159
160testme << 1
1611 << testme
162
163testme & 1
1641 & testme
165
166testme | 1
1671 | testme
168
169testme ^ 1
1701 ^ testme
171
172
173# List/dict operations
174
Martin v. Löwis3a624042006-11-08 06:46:37 +0000175class Empty: pass
176
177try:
178 1 in Empty()
179 print 'failed, should have raised TypeError'
180except TypeError:
181 pass
182
Thomas Wouters1d75a792000-08-17 22:37:32 +00001831 in testme
184
185testme[1]
186testme[1] = 1
187del testme[1]
188
189testme[:42]
190testme[:42] = "The Answer"
191del testme[:42]
192
193testme[2:1024:10]
194testme[2:1024:10] = "A lot"
195del testme[2:1024:10]
196
197testme[:42, ..., :24:, 24, 100]
198testme[:42, ..., :24:, 24, 100] = "Strange"
199del testme[:42, ..., :24:, 24, 100]
200
201
202# Now remove the slice hooks to see if converting normal slices to slice
203# object works.
204
205del AllTests.__getslice__
206del AllTests.__setslice__
207del AllTests.__delslice__
208
Barry Warsaw07d8d642001-08-20 20:29:07 +0000209import sys
210if sys.platform[:4] != 'java':
211 testme[:42]
212 testme[:42] = "The Answer"
213 del testme[:42]
214else:
215 # This works under Jython, but the actual slice values are
216 # different.
217 print "__getitem__: (slice(0, 42, None),)"
218 print "__setitem__: (slice(0, 42, None), 'The Answer')"
219 print "__delitem__: (slice(0, 42, None),)"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000220
221# Unary operations
222
223-testme
224+testme
225abs(testme)
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000226int(testme)
227long(testme)
228float(testme)
229oct(testme)
230hex(testme)
Thomas Wouters1d75a792000-08-17 22:37:32 +0000231
232# And the rest...
233
234hash(testme)
235repr(testme)
236str(testme)
237
238testme == 1
239testme < 1
240testme > 1
241testme <> 1
242testme != 1
2431 == testme
2441 < testme
2451 > testme
2461 <> testme
2471 != testme
248
249# This test has to be last (duh.)
250
251del testme
Barry Warsaw07d8d642001-08-20 20:29:07 +0000252if sys.platform[:4] == 'java':
253 import java
254 java.lang.System.gc()
Thomas Wouters1d75a792000-08-17 22:37:32 +0000255
256# Interfering tests
257
258class ExtraTests:
Fred Drake004d5e62000-10-23 17:22:08 +0000259 def __getattr__(self, *args):
260 print "__getattr__:", args
261 return "SomeVal"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000262
Fred Drake004d5e62000-10-23 17:22:08 +0000263 def __setattr__(self, *args):
264 print "__setattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000265
Fred Drake004d5e62000-10-23 17:22:08 +0000266 def __delattr__(self, *args):
267 print "__delattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000268
269testme = ExtraTests()
270testme.spam
271testme.eggs = "spam, spam, spam and ham"
272del testme.cardinal
Guido van Rossum23120242001-01-18 23:47:15 +0000273
274
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000275# return values of some method are type-checked
276class BadTypeClass:
277 def __int__(self):
278 return None
279 __float__ = __int__
280 __long__ = __int__
281 __str__ = __int__
282 __repr__ = __int__
283 __oct__ = __int__
284 __hex__ = __int__
285
286def check_exc(stmt, exception):
287 """Raise TestFailed if executing 'stmt' does not raise 'exception'
288 """
289 try:
290 exec stmt
291 except exception:
292 pass
293 else:
294 raise TestFailed, "%s should raise %s" % (stmt, exception)
295
296check_exc("int(BadTypeClass())", TypeError)
297check_exc("float(BadTypeClass())", TypeError)
298check_exc("long(BadTypeClass())", TypeError)
299check_exc("str(BadTypeClass())", TypeError)
300check_exc("repr(BadTypeClass())", TypeError)
301check_exc("oct(BadTypeClass())", TypeError)
302check_exc("hex(BadTypeClass())", TypeError)
303
304# mixing up ints and longs is okay
305class IntLongMixClass:
306 def __int__(self):
307 return 0L
308
309 def __long__(self):
310 return 0
311
312try:
313 int(IntLongMixClass())
314except TypeError:
315 raise TestFailed, "TypeError should not be raised"
316
317try:
318 long(IntLongMixClass())
319except TypeError:
320 raise TestFailed, "TypeError should not be raised"
321
322
Guido van Rossum23120242001-01-18 23:47:15 +0000323# Test correct errors from hash() on objects with comparisons but no __hash__
324
325class C0:
326 pass
327
328hash(C0()) # This should work; the next two should raise TypeError
329
330class C1:
331 def __cmp__(self, other): return 0
332
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000333check_exc("hash(C1())", TypeError)
Guido van Rossum23120242001-01-18 23:47:15 +0000334
335class C2:
336 def __eq__(self, other): return 1
337
Neil Schemenauer3a313e32004-07-19 16:29:17 +0000338check_exc("hash(C2())", TypeError)
Guido van Rossum16b93b32002-06-13 21:32:51 +0000339
340# Test for SF bug 532646
341
342class A:
343 pass
344A.__call__ = A()
345a = A()
346try:
347 a() # This should not segfault
348except RuntimeError:
349 pass
350else:
351 raise TestFailed, "how could this not have overflowed the stack?"
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000352
353
354# Tests for exceptions raised in instance_getattr2().
355
356def booh(self):
357 raise AttributeError, "booh"
358
359class A:
360 a = property(booh)
361try:
362 A().a # Raised AttributeError: A instance has no attribute 'a'
363except AttributeError, x:
Michael W. Hudsonabb103b2005-05-04 11:59:38 +0000364 if str(x) != "booh":
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000365 print "attribute error for A().a got masked:", str(x)
366
367class E:
368 __eq__ = property(booh)
369E() == E() # In debug mode, caused a C-level assert() to fail
370
371class I:
372 __init__ = property(booh)
373try:
374 I() # In debug mode, printed XXX undetected error and raises AttributeError
375except AttributeError, x:
376 pass
377else:
378 print "attribute error for I.__init__ got masked"
Armin Rigofd01d792006-06-08 10:56:24 +0000379
380
381# Test comparison and hash of methods
382class A:
383 def __init__(self, x):
384 self.x = x
385 def f(self):
386 pass
387 def g(self):
388 pass
389 def __eq__(self, other):
390 return self.x == other.x
391 def __hash__(self):
392 return self.x
393class B(A):
394 pass
395
396a1 = A(1)
397a2 = A(2)
398assert a1.f == a1.f
399assert a1.f != a2.f
400assert a1.f != a1.g
401assert a1.f == A(1).f
402assert hash(a1.f) == hash(a1.f)
403assert hash(a1.f) == hash(A(1).f)
404
405assert A.f != a1.f
406assert A.f != A.g
407assert B.f == A.f
408assert hash(B.f) == hash(A.f)
409
410# the following triggers a SystemError in 2.4
411a = A(hash(A.f.im_func)^(-1))
412hash(a.f)