PageRenderTime 31ms CodeModel.GetById 22ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_extcall.py

http://unladen-swallow.googlecode.com/
Python | 262 lines | 244 code | 16 blank | 2 comment | 6 complexity | 8bc59b3dc8d8abd242e40708502825d4 MD5 | raw file
  1"""Doctest for method/function calls.
  2
  3We're going the use these types for extra testing
  4
  5    >>> from UserList import UserList
  6    >>> from UserDict import UserDict
  7
  8We're defining four helper functions
  9
 10    >>> def e(a,b):
 11    ...     print a, b
 12
 13    >>> def f(*a, **k):
 14    ...     print a, test_support.sortdict(k)
 15
 16    >>> def g(x, *y, **z):
 17    ...     print x, y, test_support.sortdict(z)
 18
 19    >>> def h(j=1, a=2, h=3):
 20    ...     print j, a, h
 21
 22Argument list examples
 23
 24    >>> f()
 25    () {}
 26    >>> f(1)
 27    (1,) {}
 28    >>> f(1, 2)
 29    (1, 2) {}
 30    >>> f(1, 2, 3)
 31    (1, 2, 3) {}
 32    >>> f(1, 2, 3, *(4, 5))
 33    (1, 2, 3, 4, 5) {}
 34    >>> f(1, 2, 3, *[4, 5])
 35    (1, 2, 3, 4, 5) {}
 36    >>> f(1, 2, 3, *UserList([4, 5]))
 37    (1, 2, 3, 4, 5) {}
 38
 39Here we add keyword arguments
 40
 41    >>> f(1, 2, 3, **{'a':4, 'b':5})
 42    (1, 2, 3) {'a': 4, 'b': 5}
 43    >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7})
 44    (1, 2, 3, 4, 5) {'a': 6, 'b': 7}
 45    >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9})
 46    (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
 47
 48    >>> f(1, 2, 3, **UserDict(a=4, b=5))
 49    (1, 2, 3) {'a': 4, 'b': 5}
 50    >>> f(1, 2, 3, *(4, 5), **UserDict(a=6, b=7))
 51    (1, 2, 3, 4, 5) {'a': 6, 'b': 7}
 52    >>> f(1, 2, 3, x=4, y=5, *(6, 7), **UserDict(a=8, b=9))
 53    (1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5}
 54
 55Examples with invalid arguments (TypeErrors). We're also testing the function
 56names in the exception messages.
 57
 58Verify clearing of SF bug #733667
 59
 60    >>> e(c=4)
 61    Traceback (most recent call last):
 62      ...
 63    TypeError: e() got an unexpected keyword argument 'c'
 64
 65    >>> g()
 66    Traceback (most recent call last):
 67      ...
 68    TypeError: g() takes at least 1 argument (0 given)
 69
 70    >>> g(*())
 71    Traceback (most recent call last):
 72      ...
 73    TypeError: g() takes at least 1 argument (0 given)
 74
 75    >>> g(*(), **{})
 76    Traceback (most recent call last):
 77      ...
 78    TypeError: g() takes at least 1 argument (0 given)
 79
 80    >>> g(1)
 81    1 () {}
 82    >>> g(1, 2)
 83    1 (2,) {}
 84    >>> g(1, 2, 3)
 85    1 (2, 3) {}
 86    >>> g(1, 2, 3, *(4, 5))
 87    1 (2, 3, 4, 5) {}
 88
 89    >>> class Nothing: pass
 90    ...
 91    >>> g(*Nothing())
 92    Traceback (most recent call last):
 93      ...
 94    TypeError: g() argument after * must be a sequence, not instance
 95
 96    >>> class Nothing:
 97    ...     def __len__(self): return 5
 98    ...
 99
100    >>> g(*Nothing())
101    Traceback (most recent call last):
102      ...
103    TypeError: g() argument after * must be a sequence, not instance
104
105    >>> class Nothing():
106    ...     def __len__(self): return 5
107    ...     def __getitem__(self, i):
108    ...         if i<3: return i
109    ...         else: raise IndexError(i)
110    ...
111
112    >>> g(*Nothing())
113    0 (1, 2) {}
114
115    >>> class Nothing:
116    ...     def __init__(self): self.c = 0
117    ...     def __iter__(self): return self
118    ...     def next(self):
119    ...         if self.c == 4:
120    ...             raise StopIteration
121    ...         c = self.c
122    ...         self.c += 1
123    ...         return c
124    ...
125
126    >>> g(*Nothing())
127    0 (1, 2, 3) {}
128
129Make sure that the function doesn't stomp the dictionary
130
131    >>> d = {'a': 1, 'b': 2, 'c': 3}
132    >>> d2 = d.copy()
133    >>> g(1, d=4, **d)
134    1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4}
135    >>> d == d2
136    True
137
138What about willful misconduct?
139
140    >>> def saboteur(**kw):
141    ...     kw['x'] = 'm'
142    ...     return kw
143
144    >>> d = {}
145    >>> kw = saboteur(a=1, **d)
146    >>> d
147    {}
148
149
150    >>> g(1, 2, 3, **{'x': 4, 'y': 5})
151    Traceback (most recent call last):
152      ...
153    TypeError: g() got multiple values for keyword argument 'x'
154
155    >>> f(**{1:2})
156    Traceback (most recent call last):
157      ...
158    TypeError: f() keywords must be strings
159
160    >>> h(**{'e': 2})
161    Traceback (most recent call last):
162      ...
163    TypeError: h() got an unexpected keyword argument 'e'
164
165    >>> h(*h)
166    Traceback (most recent call last):
167      ...
168    TypeError: h() argument after * must be a sequence, not function
169
170    >>> dir(*h)
171    Traceback (most recent call last):
172      ...
173    TypeError: dir() argument after * must be a sequence, not function
174
175    >>> None(*h)
176    Traceback (most recent call last):
177      ...
178    TypeError: NoneType object argument after * must be a sequence, \
179not function
180
181    >>> h(**h)
182    Traceback (most recent call last):
183      ...
184    TypeError: h() argument after ** must be a mapping, not function
185
186    >>> dir(**h)
187    Traceback (most recent call last):
188      ...
189    TypeError: dir() argument after ** must be a mapping, not function
190
191    >>> None(**h)
192    Traceback (most recent call last):
193      ...
194    TypeError: NoneType object argument after ** must be a mapping, \
195not function
196
197    >>> dir(b=1, **{'b': 1})
198    Traceback (most recent call last):
199      ...
200    TypeError: dir() got multiple values for keyword argument 'b'
201
202Another helper function
203
204    >>> def f2(*a, **b):
205    ...     return a, b
206
207
208    >>> d = {}
209    >>> for i in xrange(512):
210    ...     key = 'k%d' % i
211    ...     d[key] = i
212    >>> a, b = f2(1, *(2,3), **d)
213    >>> len(a), len(b), b == d
214    (3, 512, True)
215
216    >>> class Foo:
217    ...     def method(self, arg1, arg2):
218    ...         return arg1+arg2
219
220    >>> x = Foo()
221    >>> Foo.method(*(x, 1, 2))
222    3
223    >>> Foo.method(x, *(1, 2))
224    3
225    >>> Foo.method(*(1, 2, 3))
226    Traceback (most recent call last):
227      ...
228    TypeError: unbound method method() must be called with Foo instance as \
229first argument (got int instance instead)
230
231    >>> Foo.method(1, *[2, 3])
232    Traceback (most recent call last):
233      ...
234    TypeError: unbound method method() must be called with Foo instance as \
235first argument (got int instance instead)
236
237A PyCFunction that takes only positional parameters shoud allow an
238empty keyword dictionary to pass without a complaint, but raise a
239TypeError if te dictionary is not empty
240
241    >>> try:
242    ...     silence = id(1, *{})
243    ...     True
244    ... except:
245    ...     False
246    True
247
248    >>> id(1, **{'foo': 1})
249    Traceback (most recent call last):
250      ...
251    TypeError: id() takes no keyword arguments
252
253"""
254
255from test import test_support
256
257def test_main():
258    from test import test_extcall # self import
259    test_support.run_doctest(test_extcall, True)
260
261if __name__ == '__main__':
262    test_main()