blob: 362c31c40c4ad64ed97b12970a2636ee74eaa909 [file] [log] [blame]
Victor Stinner3b5cf852017-06-09 16:48:45 +02001import datetime
Jeremy Hyltonbea39472001-05-29 16:26:20 +00002import unittest
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +03003from test.support import cpython_only
Victor Stinner3b5cf852017-06-09 16:48:45 +02004try:
5 import _testcapi
6except ImportError:
7 _testcapi = None
Sylvain96c7c062017-06-15 17:05:23 +02008import struct
9import collections
Oren Milmanbf9075a2017-08-23 21:16:48 +030010import itertools
Jeremy Hyltonbea39472001-05-29 16:26:20 +000011
Miss Islington (bot)12e3e802018-09-25 21:17:52 -070012
13class FunctionCalls(unittest.TestCase):
14
15 def test_kwargs_order(self):
16 # bpo-34320: **kwargs should preserve order of passed OrderedDict
17 od = collections.OrderedDict([('a', 1), ('b', 2)])
18 od.move_to_end('a')
19 expected = list(od.items())
20
21 def fn(**kw):
22 return kw
23
24 res = fn(**od)
25 self.assertIsInstance(res, dict)
26 self.assertEqual(list(res.items()), expected)
27
28
Jeremy Hyltonbea39472001-05-29 16:26:20 +000029# The test cases here cover several paths through the function calling
30# code. They depend on the METH_XXX flag that is used to define a C
31# function, which can't be verified from Python. If the METH_XXX decl
32# for a C function changes, these tests may not cover the right paths.
33
34class CFunctionCalls(unittest.TestCase):
35
36 def test_varargs0(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000037 self.assertRaises(TypeError, {}.__contains__)
Jeremy Hyltonbea39472001-05-29 16:26:20 +000038
39 def test_varargs1(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000040 {}.__contains__(0)
Jeremy Hyltonbea39472001-05-29 16:26:20 +000041
42 def test_varargs2(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000043 self.assertRaises(TypeError, {}.__contains__, 0, 1)
Jeremy Hyltonbea39472001-05-29 16:26:20 +000044
45 def test_varargs0_ext(self):
46 try:
Guido van Rossume2b70bc2006-08-18 22:13:04 +000047 {}.__contains__(*())
Jeremy Hyltonbea39472001-05-29 16:26:20 +000048 except TypeError:
49 pass
50
51 def test_varargs1_ext(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000052 {}.__contains__(*(0,))
Jeremy Hyltonbea39472001-05-29 16:26:20 +000053
54 def test_varargs2_ext(self):
55 try:
Guido van Rossume2b70bc2006-08-18 22:13:04 +000056 {}.__contains__(*(1, 2))
Jeremy Hyltonbea39472001-05-29 16:26:20 +000057 except TypeError:
58 pass
59 else:
60 raise RuntimeError
61
Jeremy Hyltonbea39472001-05-29 16:26:20 +000062 def test_varargs1_kw(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000063 self.assertRaises(TypeError, {}.__contains__, x=2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +000064
65 def test_varargs2_kw(self):
Guido van Rossume2b70bc2006-08-18 22:13:04 +000066 self.assertRaises(TypeError, {}.__contains__, x=2, y=2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +000067
68 def test_oldargs0_0(self):
69 {}.keys()
70
71 def test_oldargs0_1(self):
72 self.assertRaises(TypeError, {}.keys, 0)
73
74 def test_oldargs0_2(self):
75 self.assertRaises(TypeError, {}.keys, 0, 1)
76
77 def test_oldargs0_0_ext(self):
78 {}.keys(*())
79
80 def test_oldargs0_1_ext(self):
81 try:
82 {}.keys(*(0,))
83 except TypeError:
84 pass
85 else:
86 raise RuntimeError
87
88 def test_oldargs0_2_ext(self):
89 try:
90 {}.keys(*(1, 2))
91 except TypeError:
92 pass
93 else:
94 raise RuntimeError
95
96 def test_oldargs0_0_kw(self):
97 try:
98 {}.keys(x=2)
99 except TypeError:
100 pass
101 else:
102 raise RuntimeError
103
104 def test_oldargs0_1_kw(self):
105 self.assertRaises(TypeError, {}.keys, x=2)
106
107 def test_oldargs0_2_kw(self):
108 self.assertRaises(TypeError, {}.keys, x=2, y=2)
109
110 def test_oldargs1_0(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000111 self.assertRaises(TypeError, [].count)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000112
113 def test_oldargs1_1(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000114 [].count(1)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000115
116 def test_oldargs1_2(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000117 self.assertRaises(TypeError, [].count, 1, 2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000118
119 def test_oldargs1_0_ext(self):
120 try:
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000121 [].count(*())
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000122 except TypeError:
123 pass
124 else:
125 raise RuntimeError
126
127 def test_oldargs1_1_ext(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000128 [].count(*(1,))
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000129
130 def test_oldargs1_2_ext(self):
131 try:
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000132 [].count(*(1, 2))
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000133 except TypeError:
134 pass
135 else:
136 raise RuntimeError
137
138 def test_oldargs1_0_kw(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000139 self.assertRaises(TypeError, [].count, x=2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000140
141 def test_oldargs1_1_kw(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000142 self.assertRaises(TypeError, [].count, {}, x=2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000143
144 def test_oldargs1_2_kw(self):
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000145 self.assertRaises(TypeError, [].count, x=2, y=2)
Jeremy Hyltonbea39472001-05-29 16:26:20 +0000146
Fred Drake2e2be372001-09-20 21:33:42 +0000147
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +0300148@cpython_only
149class CFunctionCallsErrorMessages(unittest.TestCase):
150
151 def test_varargs0(self):
152 msg = r"__contains__\(\) takes exactly one argument \(0 given\)"
153 self.assertRaisesRegex(TypeError, msg, {}.__contains__)
154
155 def test_varargs2(self):
156 msg = r"__contains__\(\) takes exactly one argument \(2 given\)"
157 self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1)
158
Serhiy Storchakaf9f1cca2017-06-09 19:27:06 +0300159 def test_varargs3(self):
160 msg = r"^from_bytes\(\) takes at most 2 positional arguments \(3 given\)"
161 self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)
162
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +0300163 def test_varargs1_kw(self):
164 msg = r"__contains__\(\) takes no keyword arguments"
165 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2)
166
167 def test_varargs2_kw(self):
168 msg = r"__contains__\(\) takes no keyword arguments"
169 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2)
170
Sylvain74453812017-06-10 06:51:48 +0200171 def test_varargs3_kw(self):
172 msg = r"bool\(\) takes no keyword arguments"
173 self.assertRaisesRegex(TypeError, msg, bool, x=2)
174
175 def test_varargs4_kw(self):
176 msg = r"^index\(\) takes no keyword arguments$"
177 self.assertRaisesRegex(TypeError, msg, [].index, x=2)
178
179 def test_varargs5_kw(self):
180 msg = r"^hasattr\(\) takes no keyword arguments$"
181 self.assertRaisesRegex(TypeError, msg, hasattr, x=2)
182
Sylvain96c7c062017-06-15 17:05:23 +0200183 def test_varargs6_kw(self):
184 msg = r"^getattr\(\) takes no keyword arguments$"
185 self.assertRaisesRegex(TypeError, msg, getattr, x=2)
186
187 def test_varargs7_kw(self):
188 msg = r"^next\(\) takes no keyword arguments$"
189 self.assertRaisesRegex(TypeError, msg, next, x=2)
190
191 def test_varargs8_kw(self):
192 msg = r"^pack\(\) takes no keyword arguments$"
193 self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)
194
195 def test_varargs9_kw(self):
196 msg = r"^pack_into\(\) takes no keyword arguments$"
197 self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)
198
199 def test_varargs10_kw(self):
200 msg = r"^index\(\) takes no keyword arguments$"
201 self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)
202
203 def test_varargs11_kw(self):
204 msg = r"^pack\(\) takes no keyword arguments$"
205 self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)
206
Sylvain96480882017-07-09 05:45:06 +0200207 def test_varargs12_kw(self):
208 msg = r"^staticmethod\(\) takes no keyword arguments$"
209 self.assertRaisesRegex(TypeError, msg, staticmethod, func=id)
210
211 def test_varargs13_kw(self):
212 msg = r"^classmethod\(\) takes no keyword arguments$"
213 self.assertRaisesRegex(TypeError, msg, classmethod, func=id)
214
Oren Milmanbf9075a2017-08-23 21:16:48 +0300215 def test_varargs14_kw(self):
216 msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$"
217 self.assertRaisesRegex(TypeError, msg,
218 itertools.product, 0, repeat=1, foo=2)
219
220 def test_varargs15_kw(self):
221 msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$"
222 self.assertRaisesRegex(TypeError, msg,
223 ImportError, 0, name=1, path=2, foo=3)
224
225 def test_varargs16_kw(self):
226 msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$"
227 self.assertRaisesRegex(TypeError, msg,
228 min, 0, default=1, key=2, foo=3)
229
230 def test_varargs17_kw(self):
231 msg = r"^print\(\) takes at most 4 keyword arguments \(5 given\)$"
232 self.assertRaisesRegex(TypeError, msg,
233 print, 0, sep=1, end=2, file=3, flush=4, foo=5)
234
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +0300235 def test_oldargs0_1(self):
236 msg = r"keys\(\) takes no arguments \(1 given\)"
237 self.assertRaisesRegex(TypeError, msg, {}.keys, 0)
238
239 def test_oldargs0_2(self):
240 msg = r"keys\(\) takes no arguments \(2 given\)"
241 self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1)
242
243 def test_oldargs0_1_kw(self):
244 msg = r"keys\(\) takes no keyword arguments"
245 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2)
246
247 def test_oldargs0_2_kw(self):
248 msg = r"keys\(\) takes no keyword arguments"
249 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2)
250
251 def test_oldargs1_0(self):
252 msg = r"count\(\) takes exactly one argument \(0 given\)"
253 self.assertRaisesRegex(TypeError, msg, [].count)
254
255 def test_oldargs1_2(self):
256 msg = r"count\(\) takes exactly one argument \(2 given\)"
257 self.assertRaisesRegex(TypeError, msg, [].count, 1, 2)
258
259 def test_oldargs1_0_kw(self):
260 msg = r"count\(\) takes no keyword arguments"
261 self.assertRaisesRegex(TypeError, msg, [].count, x=2)
262
263 def test_oldargs1_1_kw(self):
264 msg = r"count\(\) takes no keyword arguments"
265 self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2)
266
267 def test_oldargs1_2_kw(self):
268 msg = r"count\(\) takes no keyword arguments"
269 self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2)
270
271
Victor Stinner3b5cf852017-06-09 16:48:45 +0200272def pyfunc(arg1, arg2):
273 return [arg1, arg2]
274
275
276def pyfunc_noarg():
277 return "noarg"
278
279
280class PythonClass:
281 def method(self, arg1, arg2):
282 return [arg1, arg2]
283
284 def method_noarg(self):
285 return "noarg"
286
287 @classmethod
288 def class_method(cls):
289 return "classmethod"
290
291 @staticmethod
292 def static_method():
293 return "staticmethod"
294
295
296PYTHON_INSTANCE = PythonClass()
297
298
299IGNORE_RESULT = object()
300
301
302@cpython_only
303class FastCallTests(unittest.TestCase):
304 # Test calls with positional arguments
305 CALLS_POSARGS = (
306 # (func, args: tuple, result)
307
308 # Python function with 2 arguments
309 (pyfunc, (1, 2), [1, 2]),
310
311 # Python function without argument
312 (pyfunc_noarg, (), "noarg"),
313
314 # Python class methods
315 (PythonClass.class_method, (), "classmethod"),
316 (PythonClass.static_method, (), "staticmethod"),
317
318 # Python instance methods
319 (PYTHON_INSTANCE.method, (1, 2), [1, 2]),
320 (PYTHON_INSTANCE.method_noarg, (), "noarg"),
321 (PYTHON_INSTANCE.class_method, (), "classmethod"),
322 (PYTHON_INSTANCE.static_method, (), "staticmethod"),
323
324 # C function: METH_NOARGS
325 (globals, (), IGNORE_RESULT),
326
327 # C function: METH_O
328 (id, ("hello",), IGNORE_RESULT),
329
330 # C function: METH_VARARGS
331 (dir, (1,), IGNORE_RESULT),
332
333 # C function: METH_VARARGS | METH_KEYWORDS
334 (min, (5, 9), 5),
335
336 # C function: METH_FASTCALL
337 (divmod, (1000, 33), (30, 10)),
338
339 # C type static method: METH_FASTCALL | METH_CLASS
340 (int.from_bytes, (b'\x01\x00', 'little'), 1),
341
342 # bpo-30524: Test that calling a C type static method with no argument
343 # doesn't crash (ignore the result): METH_FASTCALL | METH_CLASS
344 (datetime.datetime.now, (), IGNORE_RESULT),
345 )
346
347 # Test calls with positional and keyword arguments
348 CALLS_KWARGS = (
349 # (func, args: tuple, kwargs: dict, result)
350
351 # Python function with 2 arguments
352 (pyfunc, (1,), {'arg2': 2}, [1, 2]),
353 (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
354
355 # Python instance methods
356 (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]),
357 (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
358
359 # C function: METH_VARARGS | METH_KEYWORDS
360 (max, ([],), {'default': 9}, 9),
361
362 # C type static method: METH_FASTCALL | METH_CLASS
363 (int.from_bytes, (b'\x01\x00',), {'byteorder': 'little'}, 1),
364 (int.from_bytes, (), {'bytes': b'\x01\x00', 'byteorder': 'little'}, 1),
365 )
366
367 def check_result(self, result, expected):
368 if expected is IGNORE_RESULT:
369 return
370 self.assertEqual(result, expected)
371
372 def test_fastcall(self):
373 # Test _PyObject_FastCall()
374
375 for func, args, expected in self.CALLS_POSARGS:
376 with self.subTest(func=func, args=args):
377 result = _testcapi.pyobject_fastcall(func, args)
378 self.check_result(result, expected)
379
380 if not args:
381 # args=NULL, nargs=0
382 result = _testcapi.pyobject_fastcall(func, None)
383 self.check_result(result, expected)
384
385 def test_fastcall_dict(self):
386 # Test _PyObject_FastCallDict()
387
388 for func, args, expected in self.CALLS_POSARGS:
389 with self.subTest(func=func, args=args):
390 # kwargs=NULL
391 result = _testcapi.pyobject_fastcalldict(func, args, None)
392 self.check_result(result, expected)
393
394 # kwargs={}
395 result = _testcapi.pyobject_fastcalldict(func, args, {})
396 self.check_result(result, expected)
397
398 if not args:
399 # args=NULL, nargs=0, kwargs=NULL
400 result = _testcapi.pyobject_fastcalldict(func, None, None)
401 self.check_result(result, expected)
402
403 # args=NULL, nargs=0, kwargs={}
404 result = _testcapi.pyobject_fastcalldict(func, None, {})
405 self.check_result(result, expected)
406
407 for func, args, kwargs, expected in self.CALLS_KWARGS:
408 with self.subTest(func=func, args=args, kwargs=kwargs):
409 result = _testcapi.pyobject_fastcalldict(func, args, kwargs)
410 self.check_result(result, expected)
411
412 def test_fastcall_keywords(self):
413 # Test _PyObject_FastCallKeywords()
414
415 for func, args, expected in self.CALLS_POSARGS:
416 with self.subTest(func=func, args=args):
417 # kwnames=NULL
418 result = _testcapi.pyobject_fastcallkeywords(func, args, None)
419 self.check_result(result, expected)
420
421 # kwnames=()
422 result = _testcapi.pyobject_fastcallkeywords(func, args, ())
423 self.check_result(result, expected)
424
425 if not args:
426 # kwnames=NULL
427 result = _testcapi.pyobject_fastcallkeywords(func, None, None)
428 self.check_result(result, expected)
429
430 # kwnames=()
431 result = _testcapi.pyobject_fastcallkeywords(func, None, ())
432 self.check_result(result, expected)
433
434 for func, args, kwargs, expected in self.CALLS_KWARGS:
435 with self.subTest(func=func, args=args, kwargs=kwargs):
436 kwnames = tuple(kwargs.keys())
437 args = args + tuple(kwargs.values())
438 result = _testcapi.pyobject_fastcallkeywords(func, args, kwnames)
439 self.check_result(result, expected)
440
441
Fred Drake2e2be372001-09-20 21:33:42 +0000442if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500443 unittest.main()