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