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