• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2from test.support import cpython_only
3try:
4    import _testcapi
5except ImportError:
6    _testcapi = None
7import struct
8import collections
9import itertools
10import gc
11import contextlib
12
13
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
30@cpython_only
31class CFunctionCallsErrorMessages(unittest.TestCase):
32
33    def test_varargs0(self):
34        msg = r"__contains__\(\) takes exactly one argument \(0 given\)"
35        self.assertRaisesRegex(TypeError, msg, {}.__contains__)
36
37    def test_varargs2(self):
38        msg = r"__contains__\(\) takes exactly one argument \(2 given\)"
39        self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1)
40
41    def test_varargs3(self):
42        msg = r"^from_bytes\(\) takes exactly 2 positional arguments \(3 given\)"
43        self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)
44
45    def test_varargs1min(self):
46        msg = r"get expected at least 1 argument, got 0"
47        self.assertRaisesRegex(TypeError, msg, {}.get)
48
49        msg = r"expected 1 argument, got 0"
50        self.assertRaisesRegex(TypeError, msg, {}.__delattr__)
51
52    def test_varargs2min(self):
53        msg = r"getattr expected at least 2 arguments, got 0"
54        self.assertRaisesRegex(TypeError, msg, getattr)
55
56    def test_varargs1max(self):
57        msg = r"input expected at most 1 argument, got 2"
58        self.assertRaisesRegex(TypeError, msg, input, 1, 2)
59
60    def test_varargs2max(self):
61        msg = r"get expected at most 2 arguments, got 3"
62        self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3)
63
64    def test_varargs1_kw(self):
65        msg = r"__contains__\(\) takes no keyword arguments"
66        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2)
67
68    def test_varargs2_kw(self):
69        msg = r"__contains__\(\) takes no keyword arguments"
70        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2)
71
72    def test_varargs3_kw(self):
73        msg = r"bool\(\) takes no keyword arguments"
74        self.assertRaisesRegex(TypeError, msg, bool, x=2)
75
76    def test_varargs4_kw(self):
77        msg = r"^list[.]index\(\) takes no keyword arguments$"
78        self.assertRaisesRegex(TypeError, msg, [].index, x=2)
79
80    def test_varargs5_kw(self):
81        msg = r"^hasattr\(\) takes no keyword arguments$"
82        self.assertRaisesRegex(TypeError, msg, hasattr, x=2)
83
84    def test_varargs6_kw(self):
85        msg = r"^getattr\(\) takes no keyword arguments$"
86        self.assertRaisesRegex(TypeError, msg, getattr, x=2)
87
88    def test_varargs7_kw(self):
89        msg = r"^next\(\) takes no keyword arguments$"
90        self.assertRaisesRegex(TypeError, msg, next, x=2)
91
92    def test_varargs8_kw(self):
93        msg = r"^_struct[.]pack\(\) takes no keyword arguments$"
94        self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)
95
96    def test_varargs9_kw(self):
97        msg = r"^_struct[.]pack_into\(\) takes no keyword arguments$"
98        self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)
99
100    def test_varargs10_kw(self):
101        msg = r"^deque[.]index\(\) takes no keyword arguments$"
102        self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)
103
104    def test_varargs11_kw(self):
105        msg = r"^Struct[.]pack\(\) takes no keyword arguments$"
106        self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)
107
108    def test_varargs12_kw(self):
109        msg = r"^staticmethod\(\) takes no keyword arguments$"
110        self.assertRaisesRegex(TypeError, msg, staticmethod, func=id)
111
112    def test_varargs13_kw(self):
113        msg = r"^classmethod\(\) takes no keyword arguments$"
114        self.assertRaisesRegex(TypeError, msg, classmethod, func=id)
115
116    def test_varargs14_kw(self):
117        msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$"
118        self.assertRaisesRegex(TypeError, msg,
119                               itertools.product, 0, repeat=1, foo=2)
120
121    def test_varargs15_kw(self):
122        msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$"
123        self.assertRaisesRegex(TypeError, msg,
124                               ImportError, 0, name=1, path=2, foo=3)
125
126    def test_varargs16_kw(self):
127        msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$"
128        self.assertRaisesRegex(TypeError, msg,
129                               min, 0, default=1, key=2, foo=3)
130
131    def test_varargs17_kw(self):
132        msg = r"^print\(\) takes at most 4 keyword arguments \(5 given\)$"
133        self.assertRaisesRegex(TypeError, msg,
134                               print, 0, sep=1, end=2, file=3, flush=4, foo=5)
135
136    def test_oldargs0_1(self):
137        msg = r"keys\(\) takes no arguments \(1 given\)"
138        self.assertRaisesRegex(TypeError, msg, {}.keys, 0)
139
140    def test_oldargs0_2(self):
141        msg = r"keys\(\) takes no arguments \(2 given\)"
142        self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1)
143
144    def test_oldargs0_1_kw(self):
145        msg = r"keys\(\) takes no keyword arguments"
146        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2)
147
148    def test_oldargs0_2_kw(self):
149        msg = r"keys\(\) takes no keyword arguments"
150        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2)
151
152    def test_oldargs1_0(self):
153        msg = r"count\(\) takes exactly one argument \(0 given\)"
154        self.assertRaisesRegex(TypeError, msg, [].count)
155
156    def test_oldargs1_2(self):
157        msg = r"count\(\) takes exactly one argument \(2 given\)"
158        self.assertRaisesRegex(TypeError, msg, [].count, 1, 2)
159
160    def test_oldargs1_0_kw(self):
161        msg = r"count\(\) takes no keyword arguments"
162        self.assertRaisesRegex(TypeError, msg, [].count, x=2)
163
164    def test_oldargs1_1_kw(self):
165        msg = r"count\(\) takes no keyword arguments"
166        self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2)
167
168    def test_oldargs1_2_kw(self):
169        msg = r"count\(\) takes no keyword arguments"
170        self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2)
171
172
173
174class TestCallingConventions(unittest.TestCase):
175    """Test calling using various C calling conventions (METH_*) from Python
176
177    Subclasses test several kinds of functions (module-level, methods,
178    class methods static methods) using these attributes:
179      obj: the object that contains tested functions (as attributes)
180      expected_self: expected "self" argument to the C function
181
182    The base class tests module-level functions.
183    """
184
185    def setUp(self):
186        self.obj = self.expected_self = _testcapi
187
188    def test_varargs(self):
189        self.assertEqual(
190            self.obj.meth_varargs(1, 2, 3),
191            (self.expected_self, (1, 2, 3)),
192        )
193
194    def test_varargs_ext(self):
195        self.assertEqual(
196            self.obj.meth_varargs(*(1, 2, 3)),
197            (self.expected_self, (1, 2, 3)),
198        )
199
200    def test_varargs_error_kw(self):
201        msg = r"meth_varargs\(\) takes no keyword arguments"
202        self.assertRaisesRegex(
203            TypeError, msg, lambda: self.obj.meth_varargs(k=1),
204        )
205
206    def test_varargs_keywords(self):
207        self.assertEqual(
208            self.obj.meth_varargs_keywords(1, 2, a=3, b=4),
209            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
210        )
211
212    def test_varargs_keywords_ext(self):
213        self.assertEqual(
214            self.obj.meth_varargs_keywords(*[1, 2], **{'a': 3, 'b': 4}),
215            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
216        )
217
218    def test_o(self):
219        self.assertEqual(self.obj.meth_o(1), (self.expected_self, 1))
220
221    def test_o_ext(self):
222        self.assertEqual(self.obj.meth_o(*[1]), (self.expected_self, 1))
223
224    def test_o_error_no_arg(self):
225        msg = r"meth_o\(\) takes exactly one argument \(0 given\)"
226        self.assertRaisesRegex(TypeError, msg, self.obj.meth_o)
227
228    def test_o_error_two_args(self):
229        msg = r"meth_o\(\) takes exactly one argument \(2 given\)"
230        self.assertRaisesRegex(
231            TypeError, msg, lambda: self.obj.meth_o(1, 2),
232        )
233
234    def test_o_error_ext(self):
235        msg = r"meth_o\(\) takes exactly one argument \(3 given\)"
236        self.assertRaisesRegex(
237            TypeError, msg, lambda: self.obj.meth_o(*(1, 2, 3)),
238        )
239
240    def test_o_error_kw(self):
241        msg = r"meth_o\(\) takes no keyword arguments"
242        self.assertRaisesRegex(
243            TypeError, msg, lambda: self.obj.meth_o(k=1),
244        )
245
246    def test_o_error_arg_kw(self):
247        msg = r"meth_o\(\) takes no keyword arguments"
248        self.assertRaisesRegex(
249            TypeError, msg, lambda: self.obj.meth_o(k=1),
250        )
251
252    def test_noargs(self):
253        self.assertEqual(self.obj.meth_noargs(), self.expected_self)
254
255    def test_noargs_ext(self):
256        self.assertEqual(self.obj.meth_noargs(*[]), self.expected_self)
257
258    def test_noargs_error_arg(self):
259        msg = r"meth_noargs\(\) takes no arguments \(1 given\)"
260        self.assertRaisesRegex(
261            TypeError, msg, lambda: self.obj.meth_noargs(1),
262        )
263
264    def test_noargs_error_arg2(self):
265        msg = r"meth_noargs\(\) takes no arguments \(2 given\)"
266        self.assertRaisesRegex(
267            TypeError, msg, lambda: self.obj.meth_noargs(1, 2),
268        )
269
270    def test_noargs_error_ext(self):
271        msg = r"meth_noargs\(\) takes no arguments \(3 given\)"
272        self.assertRaisesRegex(
273            TypeError, msg, lambda: self.obj.meth_noargs(*(1, 2, 3)),
274        )
275
276    def test_noargs_error_kw(self):
277        msg = r"meth_noargs\(\) takes no keyword arguments"
278        self.assertRaisesRegex(
279            TypeError, msg, lambda: self.obj.meth_noargs(k=1),
280        )
281
282    def test_fastcall(self):
283        self.assertEqual(
284            self.obj.meth_fastcall(1, 2, 3),
285            (self.expected_self, (1, 2, 3)),
286        )
287
288    def test_fastcall_ext(self):
289        self.assertEqual(
290            self.obj.meth_fastcall(*(1, 2, 3)),
291            (self.expected_self, (1, 2, 3)),
292        )
293
294    def test_fastcall_error_kw(self):
295        msg = r"meth_fastcall\(\) takes no keyword arguments"
296        self.assertRaisesRegex(
297            TypeError, msg, lambda: self.obj.meth_fastcall(k=1),
298        )
299
300    def test_fastcall_keywords(self):
301        self.assertEqual(
302            self.obj.meth_fastcall_keywords(1, 2, a=3, b=4),
303            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
304        )
305
306    def test_fastcall_keywords_ext(self):
307        self.assertEqual(
308            self.obj.meth_fastcall_keywords(*(1, 2), **{'a': 3, 'b': 4}),
309            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
310        )
311
312
313class TestCallingConventionsInstance(TestCallingConventions):
314    """Test calling instance methods using various calling conventions"""
315
316    def setUp(self):
317        self.obj = self.expected_self = _testcapi.MethInstance()
318
319
320class TestCallingConventionsClass(TestCallingConventions):
321    """Test calling class methods using various calling conventions"""
322
323    def setUp(self):
324        self.obj = self.expected_self = _testcapi.MethClass
325
326
327class TestCallingConventionsClassInstance(TestCallingConventions):
328    """Test calling class methods on instance"""
329
330    def setUp(self):
331        self.obj = _testcapi.MethClass()
332        self.expected_self = _testcapi.MethClass
333
334
335class TestCallingConventionsStatic(TestCallingConventions):
336    """Test calling static methods using various calling conventions"""
337
338    def setUp(self):
339        self.obj = _testcapi.MethStatic()
340        self.expected_self = None
341
342
343def pyfunc(arg1, arg2):
344    return [arg1, arg2]
345
346
347def pyfunc_noarg():
348    return "noarg"
349
350
351class PythonClass:
352    def method(self, arg1, arg2):
353        return [arg1, arg2]
354
355    def method_noarg(self):
356        return "noarg"
357
358    @classmethod
359    def class_method(cls):
360        return "classmethod"
361
362    @staticmethod
363    def static_method():
364        return "staticmethod"
365
366
367PYTHON_INSTANCE = PythonClass()
368
369NULL_OR_EMPTY = object()
370
371class FastCallTests(unittest.TestCase):
372    """Test calling using various callables from C
373    """
374
375    # Test calls with positional arguments
376    CALLS_POSARGS = [
377        # (func, args: tuple, result)
378
379        # Python function with 2 arguments
380        (pyfunc, (1, 2), [1, 2]),
381
382        # Python function without argument
383        (pyfunc_noarg, (), "noarg"),
384
385        # Python class methods
386        (PythonClass.class_method, (), "classmethod"),
387        (PythonClass.static_method, (), "staticmethod"),
388
389        # Python instance methods
390        (PYTHON_INSTANCE.method, (1, 2), [1, 2]),
391        (PYTHON_INSTANCE.method_noarg, (), "noarg"),
392        (PYTHON_INSTANCE.class_method, (), "classmethod"),
393        (PYTHON_INSTANCE.static_method, (), "staticmethod"),
394
395        # C callables are added later
396    ]
397
398    # Test calls with positional and keyword arguments
399    CALLS_KWARGS = [
400        # (func, args: tuple, kwargs: dict, result)
401
402        # Python function with 2 arguments
403        (pyfunc, (1,), {'arg2': 2}, [1, 2]),
404        (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
405
406        # Python instance methods
407        (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]),
408        (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
409
410        # C callables are added later
411    ]
412
413    # Add all the calling conventions and variants of C callables
414    _instance = _testcapi.MethInstance()
415    for obj, expected_self in (
416        (_testcapi, _testcapi),  # module-level function
417        (_instance, _instance),  # bound method
418        (_testcapi.MethClass, _testcapi.MethClass),  # class method on class
419        (_testcapi.MethClass(), _testcapi.MethClass),  # class method on inst.
420        (_testcapi.MethStatic, None),  # static method
421    ):
422        CALLS_POSARGS.extend([
423            (obj.meth_varargs, (1, 2), (expected_self, (1, 2))),
424            (obj.meth_varargs_keywords,
425                (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
426            (obj.meth_fastcall, (1, 2), (expected_self, (1, 2))),
427            (obj.meth_fastcall, (), (expected_self, ())),
428            (obj.meth_fastcall_keywords,
429                (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
430            (obj.meth_fastcall_keywords,
431                (), (expected_self, (), NULL_OR_EMPTY)),
432            (obj.meth_noargs, (), expected_self),
433            (obj.meth_o, (123, ), (expected_self, 123)),
434        ])
435
436        CALLS_KWARGS.extend([
437            (obj.meth_varargs_keywords,
438                (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
439            (obj.meth_varargs_keywords,
440                (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
441            (obj.meth_varargs_keywords,
442                (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
443            (obj.meth_fastcall_keywords,
444                (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
445            (obj.meth_fastcall_keywords,
446                (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
447            (obj.meth_fastcall_keywords,
448                (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
449        ])
450
451    def check_result(self, result, expected):
452        if isinstance(expected, tuple) and expected[-1] is NULL_OR_EMPTY:
453            if result[-1] in ({}, None):
454                expected = (*expected[:-1], result[-1])
455        self.assertEqual(result, expected)
456
457    def test_fastcall(self):
458        # Test _PyObject_FastCall()
459
460        for func, args, expected in self.CALLS_POSARGS:
461            with self.subTest(func=func, args=args):
462                result = _testcapi.pyobject_fastcall(func, args)
463                self.check_result(result, expected)
464
465                if not args:
466                    # args=NULL, nargs=0
467                    result = _testcapi.pyobject_fastcall(func, None)
468                    self.check_result(result, expected)
469
470    def test_vectorcall_dict(self):
471        # Test PyObject_VectorcallDict()
472
473        for func, args, expected in self.CALLS_POSARGS:
474            with self.subTest(func=func, args=args):
475                # kwargs=NULL
476                result = _testcapi.pyobject_fastcalldict(func, args, None)
477                self.check_result(result, expected)
478
479                if not args:
480                    # args=NULL, nargs=0, kwargs=NULL
481                    result = _testcapi.pyobject_fastcalldict(func, None, None)
482                    self.check_result(result, expected)
483
484        for func, args, kwargs, expected in self.CALLS_KWARGS:
485            with self.subTest(func=func, args=args, kwargs=kwargs):
486                result = _testcapi.pyobject_fastcalldict(func, args, kwargs)
487                self.check_result(result, expected)
488
489    def test_vectorcall(self):
490        # Test PyObject_Vectorcall()
491
492        for func, args, expected in self.CALLS_POSARGS:
493            with self.subTest(func=func, args=args):
494                # kwnames=NULL
495                result = _testcapi.pyobject_vectorcall(func, args, None)
496                self.check_result(result, expected)
497
498                # kwnames=()
499                result = _testcapi.pyobject_vectorcall(func, args, ())
500                self.check_result(result, expected)
501
502                if not args:
503                    # kwnames=NULL
504                    result = _testcapi.pyobject_vectorcall(func, None, None)
505                    self.check_result(result, expected)
506
507                    # kwnames=()
508                    result = _testcapi.pyobject_vectorcall(func, None, ())
509                    self.check_result(result, expected)
510
511        for func, args, kwargs, expected in self.CALLS_KWARGS:
512            with self.subTest(func=func, args=args, kwargs=kwargs):
513                kwnames = tuple(kwargs.keys())
514                args = args + tuple(kwargs.values())
515                result = _testcapi.pyobject_vectorcall(func, args, kwnames)
516                self.check_result(result, expected)
517
518    def test_fastcall_clearing_dict(self):
519        # Test bpo-36907: the point of the test is just checking that this
520        # does not crash.
521        class IntWithDict:
522            __slots__ = ["kwargs"]
523            def __init__(self, **kwargs):
524                self.kwargs = kwargs
525            def __index__(self):
526                self.kwargs.clear()
527                gc.collect()
528                return 0
529        x = IntWithDict(dont_inherit=IntWithDict())
530        # We test the argument handling of "compile" here, the compilation
531        # itself is not relevant. When we pass flags=x below, x.__index__() is
532        # called, which changes the keywords dict.
533        compile("pass", "", "exec", x, **x.kwargs)
534
535
536Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11
537Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17
538
539
540def testfunction(self):
541    """some doc"""
542    return self
543
544
545def testfunction_kw(self, *, kw):
546    """some doc"""
547    return self
548
549
550class TestPEP590(unittest.TestCase):
551
552    def test_method_descriptor_flag(self):
553        import functools
554        cached = functools.lru_cache(1)(testfunction)
555
556        self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
557        self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
558        self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
559        self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
560        self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
561
562        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
563        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
564        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
565
566        # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
567        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
568            pass
569        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
570
571    def test_vectorcall_flag(self):
572        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
573        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
574        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
575        self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
576
577        # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL
578        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
579            pass
580        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
581
582    def test_vectorcall_override(self):
583        # Check that tp_call can correctly override vectorcall.
584        # MethodDescriptorNopGet implements tp_call but it inherits from
585        # MethodDescriptorBase, which implements vectorcall. Since
586        # MethodDescriptorNopGet returns the args tuple when called, we check
587        # additionally that no new tuple is created for this call.
588        args = tuple(range(5))
589        f = _testcapi.MethodDescriptorNopGet()
590        self.assertIs(f(*args), args)
591
592    def test_vectorcall(self):
593        # Test a bunch of different ways to call objects:
594        # 1. vectorcall using PyVectorcall_Call()
595        #   (only for objects that support vectorcall directly)
596        # 2. normal call
597        # 3. vectorcall using PyObject_Vectorcall()
598        # 4. call as bound method
599        # 5. call using functools.partial
600
601        # A list of (function, args, kwargs, result) calls to test
602        calls = [(len, (range(42),), {}, 42),
603                 (list.append, ([], 0), {}, None),
604                 ([].append, (0,), {}, None),
605                 (sum, ([36],), {"start":6}, 42),
606                 (testfunction, (42,), {}, 42),
607                 (testfunction_kw, (42,), {"kw":None}, 42),
608                 (_testcapi.MethodDescriptorBase(), (0,), {}, True),
609                 (_testcapi.MethodDescriptorDerived(), (0,), {}, True),
610                 (_testcapi.MethodDescriptor2(), (0,), {}, False)]
611
612        from _testcapi import pyobject_vectorcall, pyvectorcall_call
613        from types import MethodType
614        from functools import partial
615
616        def vectorcall(func, args, kwargs):
617            args = *args, *kwargs.values()
618            kwnames = tuple(kwargs)
619            return pyobject_vectorcall(func, args, kwnames)
620
621        for (func, args, kwargs, expected) in calls:
622            with self.subTest(str(func)):
623                if not kwargs:
624                    self.assertEqual(expected, pyvectorcall_call(func, args))
625                self.assertEqual(expected, pyvectorcall_call(func, args, kwargs))
626
627        # Add derived classes (which do not support vectorcall directly,
628        # but do support all other ways of calling).
629
630        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
631            pass
632
633        class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase):
634            def __call__(self, n):
635                return 'new'
636
637        class SuperBase:
638            def __call__(self, *args):
639                return super().__call__(*args)
640
641        class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase):
642            def __call__(self, *args):
643                return super().__call__(*args)
644
645        calls += [
646            (dict.update, ({},), {"key":True}, None),
647            ({}.update, ({},), {"key":True}, None),
648            (MethodDescriptorHeap(), (0,), {}, True),
649            (MethodDescriptorOverridden(), (0,), {}, 'new'),
650            (MethodDescriptorSuper(), (0,), {}, True),
651        ]
652
653        for (func, args, kwargs, expected) in calls:
654            with self.subTest(str(func)):
655                args1 = args[1:]
656                meth = MethodType(func, args[0])
657                wrapped = partial(func)
658                if not kwargs:
659                    self.assertEqual(expected, func(*args))
660                    self.assertEqual(expected, pyobject_vectorcall(func, args, None))
661                    self.assertEqual(expected, meth(*args1))
662                    self.assertEqual(expected, wrapped(*args))
663                self.assertEqual(expected, func(*args, **kwargs))
664                self.assertEqual(expected, vectorcall(func, args, kwargs))
665                self.assertEqual(expected, meth(*args1, **kwargs))
666                self.assertEqual(expected, wrapped(*args, **kwargs))
667
668
669class A:
670    def method_two_args(self, x, y):
671        pass
672
673    @staticmethod
674    def static_no_args():
675        pass
676
677    @staticmethod
678    def positional_only(arg, /):
679        pass
680
681@cpython_only
682class TestErrorMessagesUseQualifiedName(unittest.TestCase):
683
684    @contextlib.contextmanager
685    def check_raises_type_error(self, message):
686        with self.assertRaises(TypeError) as cm:
687            yield
688        self.assertEqual(str(cm.exception), message)
689
690    def test_missing_arguments(self):
691        msg = "A.method_two_args() missing 1 required positional argument: 'y'"
692        with self.check_raises_type_error(msg):
693            A().method_two_args("x")
694
695    def test_too_many_positional(self):
696        msg = "A.static_no_args() takes 0 positional arguments but 1 was given"
697        with self.check_raises_type_error(msg):
698            A.static_no_args("oops it's an arg")
699
700    def test_positional_only_passed_as_keyword(self):
701        msg = "A.positional_only() got some positional-only arguments passed as keyword arguments: 'arg'"
702        with self.check_raises_type_error(msg):
703            A.positional_only(arg="x")
704
705    def test_unexpected_keyword(self):
706        msg = "A.method_two_args() got an unexpected keyword argument 'bad'"
707        with self.check_raises_type_error(msg):
708            A().method_two_args(bad="x")
709
710    def test_multiple_values(self):
711        msg = "A.method_two_args() got multiple values for argument 'x'"
712        with self.check_raises_type_error(msg):
713            A().method_two_args("x", "y", x="oops")
714
715
716if __name__ == "__main__":
717    unittest.main()
718