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