py-cvs-rel2_1 (Rev 1.2) merge
[python/dscho.git] / Lib / test / test_extcall.py
blob9effac7585fc48223d953d941c6f17fb47c33188
1 from test_support import verify, verbose, TestFailed, sortdict
2 from UserList import UserList
4 def f(*a, **k):
5 print a, sortdict(k)
7 def g(x, *y, **z):
8 print x, y, sortdict(z)
10 def h(j=1, a=2, h=3):
11 print j, a, h
13 f()
14 f(1)
15 f(1, 2)
16 f(1, 2, 3)
18 f(1, 2, 3, *(4, 5))
19 f(1, 2, 3, *[4, 5])
20 f(1, 2, 3, *UserList([4, 5]))
21 f(1, 2, 3, **{'a':4, 'b':5})
22 f(1, 2, 3, *(4, 5), **{'a':6, 'b':7})
23 f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b':9})
25 try:
26 g()
27 except TypeError, err:
28 print "TypeError:", err
29 else:
30 print "should raise TypeError: not enough arguments; expected 1, got 0"
32 try:
33 g(*())
34 except TypeError, err:
35 print "TypeError:", err
36 else:
37 print "should raise TypeError: not enough arguments; expected 1, got 0"
39 try:
40 g(*(), **{})
41 except TypeError, err:
42 print "TypeError:", err
43 else:
44 print "should raise TypeError: not enough arguments; expected 1, got 0"
46 g(1)
47 g(1, 2)
48 g(1, 2, 3)
49 g(1, 2, 3, *(4, 5))
50 class Nothing: pass
51 try:
52 g(*Nothing())
53 except TypeError, attr:
54 pass
55 else:
56 print "should raise TypeError"
58 class Nothing:
59 def __len__(self):
60 return 5
61 try:
62 g(*Nothing())
63 except TypeError, attr:
64 pass
65 else:
66 print "should raise TypeError"
68 class Nothing:
69 def __len__(self):
70 return 5
71 def __getitem__(self, i):
72 if i < 3:
73 return i
74 else:
75 raise IndexError, i
76 g(*Nothing())
78 # make sure the function call doesn't stomp on the dictionary?
79 d = {'a': 1, 'b': 2, 'c': 3}
80 d2 = d.copy()
81 verify(d == d2)
82 g(1, d=4, **d)
83 print sortdict(d)
84 print sortdict(d2)
85 verify(d == d2, "function call modified dictionary")
87 # what about willful misconduct?
88 def saboteur(**kw):
89 kw['x'] = locals() # yields a cyclic kw
90 return kw
91 d = {}
92 kw = saboteur(a=1, **d)
93 verify(d == {})
94 # break the cycle
95 del kw['x']
97 try:
98 g(1, 2, 3, **{'x':4, 'y':5})
99 except TypeError, err:
100 print err
101 else:
102 print "should raise TypeError: keyword parameter redefined"
104 try:
105 g(1, 2, 3, a=4, b=5, *(6, 7), **{'a':8, 'b':9})
106 except TypeError, err:
107 print err
108 else:
109 print "should raise TypeError: keyword parameter redefined"
111 try:
112 f(**{1:2})
113 except TypeError, err:
114 print err
115 else:
116 print "should raise TypeError: keywords must be strings"
118 try:
119 h(**{'e': 2})
120 except TypeError, err:
121 print err
122 else:
123 print "should raise TypeError: unexpected keyword argument: e"
125 try:
126 h(*h)
127 except TypeError, err:
128 print err
129 else:
130 print "should raise TypeError: * argument must be a tuple"
132 try:
133 dir(*h)
134 except TypeError, err:
135 print err
136 else:
137 print "should raise TypeError: * argument must be a tuple"
139 try:
140 None(*h)
141 except TypeError, err:
142 print err
143 else:
144 print "should raise TypeError: * argument must be a tuple"
146 try:
147 h(**h)
148 except TypeError, err:
149 print err
150 else:
151 print "should raise TypeError: ** argument must be a dictionary"
153 try:
154 dir(**h)
155 except TypeError, err:
156 print err
157 else:
158 print "should raise TypeError: ** argument must be a dictionary"
160 try:
161 None(**h)
162 except TypeError, err:
163 print err
164 else:
165 print "should raise TypeError: ** argument must be a dictionary"
167 try:
168 dir(b=1,**{'b':1})
169 except TypeError, err:
170 print err
171 else:
172 print "should raise TypeError: dir() got multiple values for keyword argument 'b'"
174 def f2(*a, **b):
175 return a, b
177 d = {}
178 for i in range(512):
179 key = 'k%d' % i
180 d[key] = i
181 a, b = f2(1, *(2, 3), **d)
182 print len(a), len(b), b == d
184 class Foo:
185 def method(self, arg1, arg2):
186 return arg1 + arg2
188 x = Foo()
189 print Foo.method(*(x, 1, 2))
190 print Foo.method(x, *(1, 2))
191 try:
192 print Foo.method(*(1, 2, 3))
193 except TypeError, err:
194 print err
195 try:
196 print Foo.method(1, *(2, 3))
197 except TypeError, err:
198 print err
200 # A PyCFunction that takes only positional parameters should allow an
201 # empty keyword dictionary to pass without a complaint, but raise a
202 # TypeError if the dictionary is non-empty.
203 id(1, **{})
204 try:
205 id(1, **{"foo": 1})
206 except TypeError:
207 pass
208 else:
209 raise TestFailed, 'expected TypeError; no exception raised'
211 a, b, d, e, v, k = 'A', 'B', 'D', 'E', 'V', 'K'
212 funcs = []
213 maxargs = {}
214 for args in ['', 'a', 'ab']:
215 for defargs in ['', 'd', 'de']:
216 for vararg in ['', 'v']:
217 for kwarg in ['', 'k']:
218 name = 'z' + args + defargs + vararg + kwarg
219 arglist = list(args) + map(
220 lambda x: '%s="%s"' % (x, x), defargs)
221 if vararg: arglist.append('*' + vararg)
222 if kwarg: arglist.append('**' + kwarg)
223 decl = (('def %s(%s): print "ok %s", a, b, d, e, v, ' +
224 'type(k) is type ("") and k or sortdict(k)')
225 % (name, ', '.join(arglist), name))
226 exec(decl)
227 func = eval(name)
228 funcs.append(func)
229 maxargs[func] = len(args + defargs)
231 for name in ['za', 'zade', 'zabk', 'zabdv', 'zabdevk']:
232 func = eval(name)
233 for args in [(), (1, 2), (1, 2, 3, 4, 5)]:
234 for kwargs in ['', 'a', 'd', 'ad', 'abde']:
235 kwdict = {}
236 for k in kwargs: kwdict[k] = k + k
237 print func.func_name, args, sortdict(kwdict), '->',
238 try: apply(func, args, kwdict)
239 except TypeError, err: print err