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