blob: 0da0719457f55be810529b40670f1d8b46b4a320 [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
INADA Naoki2aaf98c2018-09-26 12:59:00 +090012
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):
Serhiy Storchakaf2f55e72019-03-13 23:03:22 +0200160 msg = r"^from_bytes\(\) takes exactly 2 positional arguments \(3 given\)"
Serhiy Storchakaf9f1cca2017-06-09 19:27:06 +0300161 self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)
162
Xtreak63262782018-12-21 20:15:13 +0530163 def test_varargs1min(self):
Xtreak1426daa2018-07-23 01:43:26 +0530164 msg = r"get expected at least 1 argument, got 0"
165 self.assertRaisesRegex(TypeError, msg, {}.get)
166
Xtreak63262782018-12-21 20:15:13 +0530167 msg = r"expected 1 argument, got 0"
168 self.assertRaisesRegex(TypeError, msg, {}.__delattr__)
169
170 def test_varargs2min(self):
Xtreak1426daa2018-07-23 01:43:26 +0530171 msg = r"getattr expected at least 2 arguments, got 0"
172 self.assertRaisesRegex(TypeError, msg, getattr)
173
Xtreak63262782018-12-21 20:15:13 +0530174 def test_varargs1max(self):
Xtreak1426daa2018-07-23 01:43:26 +0530175 msg = r"input expected at most 1 argument, got 2"
176 self.assertRaisesRegex(TypeError, msg, input, 1, 2)
177
Xtreak63262782018-12-21 20:15:13 +0530178 def test_varargs2max(self):
Xtreak1426daa2018-07-23 01:43:26 +0530179 msg = r"get expected at most 2 arguments, got 3"
180 self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3)
181
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +0300182 def test_varargs1_kw(self):
183 msg = r"__contains__\(\) takes no keyword arguments"
184 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2)
185
186 def test_varargs2_kw(self):
187 msg = r"__contains__\(\) takes no keyword arguments"
188 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2)
189
Sylvain74453812017-06-10 06:51:48 +0200190 def test_varargs3_kw(self):
191 msg = r"bool\(\) takes no keyword arguments"
192 self.assertRaisesRegex(TypeError, msg, bool, x=2)
193
194 def test_varargs4_kw(self):
195 msg = r"^index\(\) takes no keyword arguments$"
196 self.assertRaisesRegex(TypeError, msg, [].index, x=2)
197
198 def test_varargs5_kw(self):
199 msg = r"^hasattr\(\) takes no keyword arguments$"
200 self.assertRaisesRegex(TypeError, msg, hasattr, x=2)
201
Sylvain96c7c062017-06-15 17:05:23 +0200202 def test_varargs6_kw(self):
203 msg = r"^getattr\(\) takes no keyword arguments$"
204 self.assertRaisesRegex(TypeError, msg, getattr, x=2)
205
206 def test_varargs7_kw(self):
207 msg = r"^next\(\) takes no keyword arguments$"
208 self.assertRaisesRegex(TypeError, msg, next, x=2)
209
210 def test_varargs8_kw(self):
211 msg = r"^pack\(\) takes no keyword arguments$"
212 self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)
213
214 def test_varargs9_kw(self):
215 msg = r"^pack_into\(\) takes no keyword arguments$"
216 self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)
217
218 def test_varargs10_kw(self):
219 msg = r"^index\(\) takes no keyword arguments$"
220 self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)
221
222 def test_varargs11_kw(self):
223 msg = r"^pack\(\) takes no keyword arguments$"
224 self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)
225
Sylvain96480882017-07-09 05:45:06 +0200226 def test_varargs12_kw(self):
227 msg = r"^staticmethod\(\) takes no keyword arguments$"
228 self.assertRaisesRegex(TypeError, msg, staticmethod, func=id)
229
230 def test_varargs13_kw(self):
231 msg = r"^classmethod\(\) takes no keyword arguments$"
232 self.assertRaisesRegex(TypeError, msg, classmethod, func=id)
233
Oren Milmanbf9075a2017-08-23 21:16:48 +0300234 def test_varargs14_kw(self):
235 msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$"
236 self.assertRaisesRegex(TypeError, msg,
237 itertools.product, 0, repeat=1, foo=2)
238
239 def test_varargs15_kw(self):
240 msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$"
241 self.assertRaisesRegex(TypeError, msg,
242 ImportError, 0, name=1, path=2, foo=3)
243
244 def test_varargs16_kw(self):
245 msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$"
246 self.assertRaisesRegex(TypeError, msg,
247 min, 0, default=1, key=2, foo=3)
248
249 def test_varargs17_kw(self):
250 msg = r"^print\(\) takes at most 4 keyword arguments \(5 given\)$"
251 self.assertRaisesRegex(TypeError, msg,
252 print, 0, sep=1, end=2, file=3, flush=4, foo=5)
253
Serhiy Storchaka5eb788b2017-06-06 18:45:22 +0300254 def test_oldargs0_1(self):
255 msg = r"keys\(\) takes no arguments \(1 given\)"
256 self.assertRaisesRegex(TypeError, msg, {}.keys, 0)
257
258 def test_oldargs0_2(self):
259 msg = r"keys\(\) takes no arguments \(2 given\)"
260 self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1)
261
262 def test_oldargs0_1_kw(self):
263 msg = r"keys\(\) takes no keyword arguments"
264 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2)
265
266 def test_oldargs0_2_kw(self):
267 msg = r"keys\(\) takes no keyword arguments"
268 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2)
269
270 def test_oldargs1_0(self):
271 msg = r"count\(\) takes exactly one argument \(0 given\)"
272 self.assertRaisesRegex(TypeError, msg, [].count)
273
274 def test_oldargs1_2(self):
275 msg = r"count\(\) takes exactly one argument \(2 given\)"
276 self.assertRaisesRegex(TypeError, msg, [].count, 1, 2)
277
278 def test_oldargs1_0_kw(self):
279 msg = r"count\(\) takes no keyword arguments"
280 self.assertRaisesRegex(TypeError, msg, [].count, x=2)
281
282 def test_oldargs1_1_kw(self):
283 msg = r"count\(\) takes no keyword arguments"
284 self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2)
285
286 def test_oldargs1_2_kw(self):
287 msg = r"count\(\) takes no keyword arguments"
288 self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2)
289
290
Victor Stinner3b5cf852017-06-09 16:48:45 +0200291def pyfunc(arg1, arg2):
292 return [arg1, arg2]
293
294
295def pyfunc_noarg():
296 return "noarg"
297
298
299class PythonClass:
300 def method(self, arg1, arg2):
301 return [arg1, arg2]
302
303 def method_noarg(self):
304 return "noarg"
305
306 @classmethod
307 def class_method(cls):
308 return "classmethod"
309
310 @staticmethod
311 def static_method():
312 return "staticmethod"
313
314
315PYTHON_INSTANCE = PythonClass()
316
317
318IGNORE_RESULT = object()
319
320
321@cpython_only
322class FastCallTests(unittest.TestCase):
323 # Test calls with positional arguments
324 CALLS_POSARGS = (
325 # (func, args: tuple, result)
326
327 # Python function with 2 arguments
328 (pyfunc, (1, 2), [1, 2]),
329
330 # Python function without argument
331 (pyfunc_noarg, (), "noarg"),
332
333 # Python class methods
334 (PythonClass.class_method, (), "classmethod"),
335 (PythonClass.static_method, (), "staticmethod"),
336
337 # Python instance methods
338 (PYTHON_INSTANCE.method, (1, 2), [1, 2]),
339 (PYTHON_INSTANCE.method_noarg, (), "noarg"),
340 (PYTHON_INSTANCE.class_method, (), "classmethod"),
341 (PYTHON_INSTANCE.static_method, (), "staticmethod"),
342
343 # C function: METH_NOARGS
344 (globals, (), IGNORE_RESULT),
345
346 # C function: METH_O
347 (id, ("hello",), IGNORE_RESULT),
348
349 # C function: METH_VARARGS
350 (dir, (1,), IGNORE_RESULT),
351
352 # C function: METH_VARARGS | METH_KEYWORDS
353 (min, (5, 9), 5),
354
355 # C function: METH_FASTCALL
356 (divmod, (1000, 33), (30, 10)),
357
358 # C type static method: METH_FASTCALL | METH_CLASS
359 (int.from_bytes, (b'\x01\x00', 'little'), 1),
360
361 # bpo-30524: Test that calling a C type static method with no argument
362 # doesn't crash (ignore the result): METH_FASTCALL | METH_CLASS
363 (datetime.datetime.now, (), IGNORE_RESULT),
364 )
365
366 # Test calls with positional and keyword arguments
367 CALLS_KWARGS = (
368 # (func, args: tuple, kwargs: dict, result)
369
370 # Python function with 2 arguments
371 (pyfunc, (1,), {'arg2': 2}, [1, 2]),
372 (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
373
374 # Python instance methods
375 (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]),
376 (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
377
378 # C function: METH_VARARGS | METH_KEYWORDS
379 (max, ([],), {'default': 9}, 9),
380
381 # C type static method: METH_FASTCALL | METH_CLASS
382 (int.from_bytes, (b'\x01\x00',), {'byteorder': 'little'}, 1),
383 (int.from_bytes, (), {'bytes': b'\x01\x00', 'byteorder': 'little'}, 1),
384 )
385
386 def check_result(self, result, expected):
387 if expected is IGNORE_RESULT:
388 return
389 self.assertEqual(result, expected)
390
391 def test_fastcall(self):
392 # Test _PyObject_FastCall()
393
394 for func, args, expected in self.CALLS_POSARGS:
395 with self.subTest(func=func, args=args):
396 result = _testcapi.pyobject_fastcall(func, args)
397 self.check_result(result, expected)
398
399 if not args:
400 # args=NULL, nargs=0
401 result = _testcapi.pyobject_fastcall(func, None)
402 self.check_result(result, expected)
403
404 def test_fastcall_dict(self):
405 # Test _PyObject_FastCallDict()
406
407 for func, args, expected in self.CALLS_POSARGS:
408 with self.subTest(func=func, args=args):
409 # kwargs=NULL
410 result = _testcapi.pyobject_fastcalldict(func, args, None)
411 self.check_result(result, expected)
412
413 # kwargs={}
414 result = _testcapi.pyobject_fastcalldict(func, args, {})
415 self.check_result(result, expected)
416
417 if not args:
418 # args=NULL, nargs=0, kwargs=NULL
419 result = _testcapi.pyobject_fastcalldict(func, None, None)
420 self.check_result(result, expected)
421
422 # args=NULL, nargs=0, kwargs={}
423 result = _testcapi.pyobject_fastcalldict(func, None, {})
424 self.check_result(result, expected)
425
426 for func, args, kwargs, expected in self.CALLS_KWARGS:
427 with self.subTest(func=func, args=args, kwargs=kwargs):
428 result = _testcapi.pyobject_fastcalldict(func, args, kwargs)
429 self.check_result(result, expected)
430
431 def test_fastcall_keywords(self):
432 # Test _PyObject_FastCallKeywords()
433
434 for func, args, expected in self.CALLS_POSARGS:
435 with self.subTest(func=func, args=args):
436 # kwnames=NULL
437 result = _testcapi.pyobject_fastcallkeywords(func, args, None)
438 self.check_result(result, expected)
439
440 # kwnames=()
441 result = _testcapi.pyobject_fastcallkeywords(func, args, ())
442 self.check_result(result, expected)
443
444 if not args:
445 # kwnames=NULL
446 result = _testcapi.pyobject_fastcallkeywords(func, None, None)
447 self.check_result(result, expected)
448
449 # kwnames=()
450 result = _testcapi.pyobject_fastcallkeywords(func, None, ())
451 self.check_result(result, expected)
452
453 for func, args, kwargs, expected in self.CALLS_KWARGS:
454 with self.subTest(func=func, args=args, kwargs=kwargs):
455 kwnames = tuple(kwargs.keys())
456 args = args + tuple(kwargs.values())
457 result = _testcapi.pyobject_fastcallkeywords(func, args, kwnames)
458 self.check_result(result, expected)
459
460
Fred Drake2e2be372001-09-20 21:33:42 +0000461if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500462 unittest.main()