blob: 7ed0e2e11998bb5bf0746db751d9eb749ae33d49 [file] [log] [blame]
Christian Heimesb186d002008-03-18 15:15:01 +00001"""Doctest for method/function calls.
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +00002
Christian Heimesb186d002008-03-18 15:15:01 +00003We're going the use these types for extra testing
Raymond Hettinger40174c32003-05-31 07:04:16 +00004
Neal Norwitzd79bacc2008-03-18 20:58:39 +00005 >>> from collections import UserList
6 >>> from collections import UserDict
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +00007
Christian Heimesb186d002008-03-18 15:15:01 +00008We're defining four helper functions
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +00009
Christian Heimesb186d002008-03-18 15:15:01 +000010 >>> def e(a,b):
Neal Norwitzd79bacc2008-03-18 20:58:39 +000011 ... print(a, b)
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +000012
Christian Heimesb186d002008-03-18 15:15:01 +000013 >>> def f(*a, **k):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000014 ... print(a, support.sortdict(k))
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +000015
Christian Heimesb186d002008-03-18 15:15:01 +000016 >>> def g(x, *y, **z):
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017 ... print(x, y, support.sortdict(z))
Christian Heimesb186d002008-03-18 15:15:01 +000018
19 >>> def h(j=1, a=2, h=3):
Neal Norwitzd79bacc2008-03-18 20:58:39 +000020 ... print(j, a, h)
Christian Heimesb186d002008-03-18 15:15:01 +000021
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 ...
Neal Norwitzd79bacc2008-03-18 20:58:39 +000068 TypeError: g() takes at least 1 positional argument (0 given)
Christian Heimesb186d002008-03-18 15:15:01 +000069
70 >>> g(*())
71 Traceback (most recent call last):
72 ...
Neal Norwitzd79bacc2008-03-18 20:58:39 +000073 TypeError: g() takes at least 1 positional argument (0 given)
Christian Heimesb186d002008-03-18 15:15:01 +000074
75 >>> g(*(), **{})
76 Traceback (most recent call last):
77 ...
Neal Norwitzd79bacc2008-03-18 20:58:39 +000078 TypeError: g() takes at least 1 positional argument (0 given)
Christian Heimesb186d002008-03-18 15:15:01 +000079
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 ...
Neal Norwitzd79bacc2008-03-18 20:58:39 +000094 TypeError: g() argument after * must be a sequence, not Nothing
Christian Heimesb186d002008-03-18 15:15:01 +000095
96 >>> class Nothing:
97 ... def __len__(self): return 5
98 ...
99
100 >>> g(*Nothing())
101 Traceback (most recent call last):
102 ...
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000103 TypeError: g() argument after * must be a sequence, not Nothing
Christian Heimesb186d002008-03-18 15:15:01 +0000104
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
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000118 ... def __next__(self):
Christian Heimesb186d002008-03-18 15:15:01 +0000119 ... 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 {}
Jeremy Hyltonaed0d8d2000-03-28 23:51:17 +0000148
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000149
Christian Heimesb186d002008-03-18 15:15:01 +0000150 >>> 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
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000206
207
Christian Heimesb186d002008-03-18 15:15:01 +0000208 >>> d = {}
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000209 >>> for i in range(512):
Christian Heimesb186d002008-03-18 15:15:01 +0000210 ... 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)
Raymond Hettinger40174c32003-05-31 07:04:16 +0000215
Christian Heimesb186d002008-03-18 15:15:01 +0000216 >>> class Foo:
217 ... def method(self, arg1, arg2):
218 ... return arg1+arg2
Fred Drake004d5e62000-10-23 17:22:08 +0000219
Christian Heimesb186d002008-03-18 15:15:01 +0000220 >>> x = Foo()
221 >>> Foo.method(*(x, 1, 2))
222 3
223 >>> Foo.method(x, *(1, 2))
224 3
225 >>> Foo.method(*(1, 2, 3))
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000226 5
Christian Heimesb186d002008-03-18 15:15:01 +0000227 >>> Foo.method(1, *[2, 3])
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000228 5
Fred Drake004d5e62000-10-23 17:22:08 +0000229
Christian Heimesb186d002008-03-18 15:15:01 +0000230A PyCFunction that takes only positional parameters shoud allow an
231empty keyword dictionary to pass without a complaint, but raise a
232TypeError if te dictionary is not empty
Jeremy Hylton074c3e62000-03-30 23:55:31 +0000233
Christian Heimesb186d002008-03-18 15:15:01 +0000234 >>> try:
235 ... silence = id(1, *{})
236 ... True
237 ... except:
238 ... False
239 True
Fred Drake004d5e62000-10-23 17:22:08 +0000240
Christian Heimesb186d002008-03-18 15:15:01 +0000241 >>> id(1, **{'foo': 1})
242 Traceback (most recent call last):
243 ...
244 TypeError: id() takes no keyword arguments
Jeremy Hylton074c3e62000-03-30 23:55:31 +0000245
Christian Heimesb186d002008-03-18 15:15:01 +0000246"""
Samuele Pedroni8036c832004-02-21 21:03:30 +0000247
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000248from test import support
Samuele Pedroni8036c832004-02-21 21:03:30 +0000249
Christian Heimesb186d002008-03-18 15:15:01 +0000250def test_main():
Neal Norwitzd79bacc2008-03-18 20:58:39 +0000251 from test import test_extcall # self import
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000252 support.run_doctest(test_extcall, True)
Jeremy Hylton074c3e62000-03-30 23:55:31 +0000253
Christian Heimesb186d002008-03-18 15:15:01 +0000254if __name__ == '__main__':
255 test_main()