blob: a37f2a47e37f6aacbbdd7b62e8e360ec64b38c34 [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",
46 "int",
47 "long",
48 "float",
49 "oct",
50 "hex",
51
52# generic operations
53 "init",
Thomas Wouters1d75a792000-08-17 22:37:32 +000054 ]
55
56# These need to return something other than None
57# "coerce",
58# "hash",
59# "str",
60# "repr",
61
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
84 def __cmp__(self, *args):
85 print "__cmp__:", args
86 return 0
87
Barry Warsaw07d8d642001-08-20 20:29:07 +000088 def __del__(self, *args):
89 print "__del__:", args
90
Tim Peters01705212001-12-11 19:28:47 +000091# Synthesize AllTests methods from the names in testmeths.
92
93method_template = """\
94def __%(method)s__(self, *args):
95 print "__%(method)s__:", args
96"""
97
Thomas Wouters1d75a792000-08-17 22:37:32 +000098for method in testmeths:
Tim Peters01705212001-12-11 19:28:47 +000099 exec method_template % locals() in AllTests.__dict__
100
101del method, method_template
Thomas Wouters1d75a792000-08-17 22:37:32 +0000102
103# this also tests __init__ of course.
104testme = AllTests()
105
106# Binary operations
107
108testme + 1
1091 + testme
110
111testme - 1
1121 - testme
113
114testme * 1
1151 * testme
116
Tim Peters01705212001-12-11 19:28:47 +0000117if 1/2 == 0:
118 testme / 1
119 1 / testme
120else:
121 # True division is in effect, so "/" doesn't map to __div__ etc; but
122 # the canned expected-output file requires that __div__ etc get called.
123 testme.__coerce__(1)
124 testme.__div__(1)
125 testme.__coerce__(1)
126 testme.__rdiv__(1)
Thomas Wouters1d75a792000-08-17 22:37:32 +0000127
128testme % 1
1291 % testme
130
131divmod(testme,1)
132divmod(1, testme)
133
134testme ** 1
1351 ** testme
136
137testme >> 1
1381 >> testme
139
140testme << 1
1411 << testme
142
143testme & 1
1441 & testme
145
146testme | 1
1471 | testme
148
149testme ^ 1
1501 ^ testme
151
152
153# List/dict operations
154
1551 in testme
156
157testme[1]
158testme[1] = 1
159del testme[1]
160
161testme[:42]
162testme[:42] = "The Answer"
163del testme[:42]
164
165testme[2:1024:10]
166testme[2:1024:10] = "A lot"
167del testme[2:1024:10]
168
169testme[:42, ..., :24:, 24, 100]
170testme[:42, ..., :24:, 24, 100] = "Strange"
171del testme[:42, ..., :24:, 24, 100]
172
173
174# Now remove the slice hooks to see if converting normal slices to slice
175# object works.
176
177del AllTests.__getslice__
178del AllTests.__setslice__
179del AllTests.__delslice__
180
Barry Warsaw07d8d642001-08-20 20:29:07 +0000181import sys
182if sys.platform[:4] != 'java':
183 testme[:42]
184 testme[:42] = "The Answer"
185 del testme[:42]
186else:
187 # This works under Jython, but the actual slice values are
188 # different.
189 print "__getitem__: (slice(0, 42, None),)"
190 print "__setitem__: (slice(0, 42, None), 'The Answer')"
191 print "__delitem__: (slice(0, 42, None),)"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000192
193# Unary operations
194
195-testme
196+testme
197abs(testme)
Barry Warsaw07d8d642001-08-20 20:29:07 +0000198if sys.platform[:4] != 'java':
199 int(testme)
200 long(testme)
201 float(testme)
202 oct(testme)
203 hex(testme)
204else:
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +0000205 # Jython enforced that these methods return
Barry Warsaw07d8d642001-08-20 20:29:07 +0000206 # a value of the expected type.
207 print "__int__: ()"
208 print "__long__: ()"
209 print "__float__: ()"
210 print "__oct__: ()"
211 print "__hex__: ()"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000212
213
214# And the rest...
215
216hash(testme)
217repr(testme)
218str(testme)
219
220testme == 1
221testme < 1
222testme > 1
223testme <> 1
224testme != 1
2251 == testme
2261 < testme
2271 > testme
2281 <> testme
2291 != testme
230
231# This test has to be last (duh.)
232
233del testme
Barry Warsaw07d8d642001-08-20 20:29:07 +0000234if sys.platform[:4] == 'java':
235 import java
236 java.lang.System.gc()
Thomas Wouters1d75a792000-08-17 22:37:32 +0000237
238# Interfering tests
239
240class ExtraTests:
Fred Drake004d5e62000-10-23 17:22:08 +0000241 def __getattr__(self, *args):
242 print "__getattr__:", args
243 return "SomeVal"
Thomas Wouters1d75a792000-08-17 22:37:32 +0000244
Fred Drake004d5e62000-10-23 17:22:08 +0000245 def __setattr__(self, *args):
246 print "__setattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000247
Fred Drake004d5e62000-10-23 17:22:08 +0000248 def __delattr__(self, *args):
249 print "__delattr__:", args
Thomas Wouters1d75a792000-08-17 22:37:32 +0000250
251testme = ExtraTests()
252testme.spam
253testme.eggs = "spam, spam, spam and ham"
254del testme.cardinal
Guido van Rossum23120242001-01-18 23:47:15 +0000255
256
257# Test correct errors from hash() on objects with comparisons but no __hash__
258
259class C0:
260 pass
261
262hash(C0()) # This should work; the next two should raise TypeError
263
264class C1:
265 def __cmp__(self, other): return 0
266
267try: hash(C1())
268except TypeError: pass
269else: raise TestFailed, "hash(C1()) should raise an exception"
270
271class C2:
272 def __eq__(self, other): return 1
273
274try: hash(C2())
275except TypeError: pass
276else: raise TestFailed, "hash(C2()) should raise an exception"
Guido van Rossum16b93b32002-06-13 21:32:51 +0000277
278
279# Test for SF bug 532646
280
281class A:
282 pass
283A.__call__ = A()
284a = A()
285try:
286 a() # This should not segfault
287except RuntimeError:
288 pass
289else:
290 raise TestFailed, "how could this not have overflowed the stack?"
Guido van Rossum2c9590f2002-10-29 19:08:29 +0000291
292
293# Tests for exceptions raised in instance_getattr2().
294
295def booh(self):
296 raise AttributeError, "booh"
297
298class A:
299 a = property(booh)
300try:
301 A().a # Raised AttributeError: A instance has no attribute 'a'
302except AttributeError, x:
303 if str(x) is not "booh":
304 print "attribute error for A().a got masked:", str(x)
305
306class E:
307 __eq__ = property(booh)
308E() == E() # In debug mode, caused a C-level assert() to fail
309
310class I:
311 __init__ = property(booh)
312try:
313 I() # In debug mode, printed XXX undetected error and raises AttributeError
314except AttributeError, x:
315 pass
316else:
317 print "attribute error for I.__init__ got masked"