test_extcall.py revision 1a7aab70d1f56b63ba6798db1cafe0a61cc3da15
1from UserList import UserList 2from test_support import TestFailed 3 4def f(*a, **k): 5 print a, k 6 7def g(x, *y, **z): 8 print x, y, z 9 10def h(j=1, a=2, h=3): 11 print j, a, h 12 13f() 14f(1) 15f(1, 2) 16f(1, 2, 3) 17 18f(1, 2, 3, *(4, 5)) 19f(1, 2, 3, *[4, 5]) 20f(1, 2, 3, *UserList([4, 5])) 21f(1, 2, 3, **{'a':4, 'b':5}) 22f(1, 2, 3, *(4, 5), **{'a':6, 'b':7}) 23f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b':9}) 24 25try: 26 g() 27except TypeError, err: 28 print "TypeError:", err 29else: 30 print "should raise TypeError: not enough arguments; expected 1, got 0" 31 32try: 33 g(*()) 34except TypeError, err: 35 print "TypeError:", err 36else: 37 print "should raise TypeError: not enough arguments; expected 1, got 0" 38 39try: 40 g(*(), **{}) 41except TypeError, err: 42 print "TypeError:", err 43else: 44 print "should raise TypeError: not enough arguments; expected 1, got 0" 45 46g(1) 47g(1, 2) 48g(1, 2, 3) 49g(1, 2, 3, *(4, 5)) 50class Nothing: pass 51try: 52 g(*Nothing()) 53except AttributeError, attr: 54 pass 55else: 56 print "should raise AttributeError: __len__" 57 58class Nothing: 59 def __len__(self): 60 return 5 61try: 62 g(*Nothing()) 63except AttributeError, attr: 64 pass 65else: 66 print "should raise AttributeError: __getitem__" 67 68class 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 76g(*Nothing()) 77 78# make sure the function call doesn't stomp on the dictionary? 79d = {'a': 1, 'b': 2, 'c': 3} 80d2 = d.copy() 81assert d == d2 82g(1, d=4, **d) 83print d 84print d2 85assert d == d2, "function call modified dictionary" 86 87# what about willful misconduct? 88def saboteur(**kw): 89 kw['x'] = locals() # yields a cyclic kw 90 return kw 91d = {} 92kw = saboteur(a=1, **d) 93assert d == {} 94# break the cycle 95del kw['x'] 96 97try: 98 g(1, 2, 3, **{'x':4, 'y':5}) 99except TypeError, err: 100 print err 101else: 102 print "should raise TypeError: keyword parameter redefined" 103 104try: 105 g(1, 2, 3, a=4, b=5, *(6, 7), **{'a':8, 'b':9}) 106except TypeError, err: 107 print err 108else: 109 print "should raise TypeError: keyword parameter redefined" 110 111try: 112 f(**{1:2}) 113except TypeError, err: 114 print err 115else: 116 print "should raise TypeError: keywords must be strings" 117 118try: 119 h(**{'e': 2}) 120except TypeError, err: 121 print err 122else: 123 print "should raise TypeError: unexpected keyword argument: e" 124 125try: 126 h(*h) 127except TypeError, err: 128 print err 129else: 130 print "should raise TypeError: * argument must be a tuple" 131 132try: 133 h(**h) 134except TypeError, err: 135 print err 136else: 137 print "should raise TypeError: ** argument must be a dictionary" 138 139def f2(*a, **b): 140 return a, b 141 142d = {} 143for i in range(512): 144 key = 'k%d' % i 145 d[key] = i 146a, b = f2(1, *(2, 3), **d) 147print len(a), len(b), b == d 148 149class Foo: 150 def method(self, arg1, arg2): 151 return arg1 + arg2 152 153x = Foo() 154print Foo.method(*(x, 1, 2)) 155print Foo.method(x, *(1, 2)) 156try: 157 print Foo.method(*(1, 2, 3)) 158except TypeError, err: 159 print err 160try: 161 print Foo.method(1, *(2, 3)) 162except TypeError, err: 163 print err 164 165# A PyCFunction that takes only positional parameters should allow an 166# empty keyword dictionary to pass without a complaint, but raise a 167# TypeError if the dictionary is non-empty. 168id(1, **{}) 169try: 170 id(1, **{"foo": 1}) 171except TypeError: 172 pass 173else: 174 raise TestFailed, 'expected TypeError; no exception raised' 175