• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2from test.support import (cpython_only, is_wasi, requires_limited_api, Py_DEBUG,
3                          set_recursion_limit, skip_on_s390x, import_helper)
4try:
5    import _testcapi
6except ImportError:
7    _testcapi = None
8try:
9    import _testlimitedcapi
10except ImportError:
11    _testlimitedcapi = None
12import struct
13import collections
14import itertools
15import gc
16import contextlib
17import sys
18import types
19
20
21class BadStr(str):
22    def __eq__(self, other):
23        return True
24    def __hash__(self):
25        # Guaranteed different hash
26        return str.__hash__(self) ^ 3
27
28
29class FunctionCalls(unittest.TestCase):
30
31    def test_kwargs_order(self):
32        # bpo-34320:  **kwargs should preserve order of passed OrderedDict
33        od = collections.OrderedDict([('a', 1), ('b', 2)])
34        od.move_to_end('a')
35        expected = list(od.items())
36
37        def fn(**kw):
38            return kw
39
40        res = fn(**od)
41        self.assertIsInstance(res, dict)
42        self.assertEqual(list(res.items()), expected)
43
44    def test_frames_are_popped_after_failed_calls(self):
45        # GH-93252: stuff blows up if we don't pop the new frame after
46        # recovering from failed calls:
47        def f():
48            pass
49        class C:
50            def m(self):
51                pass
52        callables = [f, C.m, [].__len__]
53        for c in callables:
54            for _ in range(1000):
55                try:
56                    c(None)
57                except TypeError:
58                    pass
59        # BOOM!
60
61
62@cpython_only
63class CFunctionCallsErrorMessages(unittest.TestCase):
64
65    def test_varargs0(self):
66        msg = r"__contains__\(\) takes exactly one argument \(0 given\)"
67        self.assertRaisesRegex(TypeError, msg, {}.__contains__)
68
69    def test_varargs2(self):
70        msg = r"__contains__\(\) takes exactly one argument \(2 given\)"
71        self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1)
72
73    def test_varargs3(self):
74        msg = r"^from_bytes\(\) takes at most 2 positional arguments \(3 given\)"
75        self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)
76
77    def test_varargs1min(self):
78        msg = (r"get\(\) takes at least 1 argument \(0 given\)|"
79               r"get expected at least 1 argument, got 0")
80        self.assertRaisesRegex(TypeError, msg, {}.get)
81
82        msg = r"expected 1 argument, got 0"
83        self.assertRaisesRegex(TypeError, msg, {}.__delattr__)
84
85    def test_varargs2min(self):
86        msg = r"getattr expected at least 2 arguments, got 0"
87        self.assertRaisesRegex(TypeError, msg, getattr)
88
89    def test_varargs1max(self):
90        msg = (r"input\(\) takes at most 1 argument \(2 given\)|"
91               r"input expected at most 1 argument, got 2")
92        self.assertRaisesRegex(TypeError, msg, input, 1, 2)
93
94    def test_varargs2max(self):
95        msg = (r"get\(\) takes at most 2 arguments \(3 given\)|"
96               r"get expected at most 2 arguments, got 3")
97        self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3)
98
99    def test_varargs1_kw(self):
100        msg = r"__contains__\(\) takes no keyword arguments"
101        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2)
102
103    def test_varargs2_kw(self):
104        msg = r"__contains__\(\) takes no keyword arguments"
105        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2)
106
107    def test_varargs3_kw(self):
108        msg = r"bool\(\) takes no keyword arguments"
109        self.assertRaisesRegex(TypeError, msg, bool, x=2)
110
111    def test_varargs4_kw(self):
112        msg = r"^(list[.])?index\(\) takes no keyword arguments$"
113        self.assertRaisesRegex(TypeError, msg, [].index, x=2)
114
115    def test_varargs5_kw(self):
116        msg = r"^hasattr\(\) takes no keyword arguments$"
117        self.assertRaisesRegex(TypeError, msg, hasattr, x=2)
118
119    def test_varargs6_kw(self):
120        msg = r"^getattr\(\) takes no keyword arguments$"
121        self.assertRaisesRegex(TypeError, msg, getattr, x=2)
122
123    def test_varargs7_kw(self):
124        msg = r"^next\(\) takes no keyword arguments$"
125        self.assertRaisesRegex(TypeError, msg, next, x=2)
126
127    def test_varargs8_kw(self):
128        msg = r"^_struct[.]pack\(\) takes no keyword arguments$"
129        self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)
130
131    def test_varargs9_kw(self):
132        msg = r"^_struct[.]pack_into\(\) takes no keyword arguments$"
133        self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)
134
135    def test_varargs10_kw(self):
136        msg = r"^deque[.]index\(\) takes no keyword arguments$"
137        self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)
138
139    def test_varargs11_kw(self):
140        msg = r"^Struct[.]pack\(\) takes no keyword arguments$"
141        self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)
142
143    def test_varargs12_kw(self):
144        msg = r"^staticmethod\(\) takes no keyword arguments$"
145        self.assertRaisesRegex(TypeError, msg, staticmethod, func=id)
146
147    def test_varargs13_kw(self):
148        msg = r"^classmethod\(\) takes no keyword arguments$"
149        self.assertRaisesRegex(TypeError, msg, classmethod, func=id)
150
151    def test_varargs14_kw(self):
152        msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$"
153        self.assertRaisesRegex(TypeError, msg,
154                               itertools.product, 0, repeat=1, foo=2)
155
156    def test_varargs15_kw(self):
157        msg = r"^ImportError\(\) takes at most 3 keyword arguments \(4 given\)$"
158        self.assertRaisesRegex(TypeError, msg,
159                               ImportError, 0, name=1, path=2, name_from=3, foo=3)
160
161    def test_varargs16_kw(self):
162        msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$"
163        self.assertRaisesRegex(TypeError, msg,
164                               min, 0, default=1, key=2, foo=3)
165
166    def test_varargs17_kw(self):
167        msg = r"print\(\) got an unexpected keyword argument 'foo'$"
168        self.assertRaisesRegex(TypeError, msg,
169                               print, 0, sep=1, end=2, file=3, flush=4, foo=5)
170
171    def test_varargs18_kw(self):
172        # _PyArg_UnpackKeywordsWithVararg()
173        msg = r"invalid keyword argument for print\(\)$"
174        with self.assertRaisesRegex(TypeError, msg):
175            print(0, 1, **{BadStr('foo'): ','})
176
177    def test_varargs19_kw(self):
178        # _PyArg_UnpackKeywords()
179        msg = r"invalid keyword argument for round\(\)$"
180        with self.assertRaisesRegex(TypeError, msg):
181            round(1.75, **{BadStr('foo'): 1})
182
183    def test_oldargs0_1(self):
184        msg = r"keys\(\) takes no arguments \(1 given\)"
185        self.assertRaisesRegex(TypeError, msg, {}.keys, 0)
186
187    def test_oldargs0_2(self):
188        msg = r"keys\(\) takes no arguments \(2 given\)"
189        self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1)
190
191    def test_oldargs0_1_kw(self):
192        msg = r"keys\(\) takes no keyword arguments"
193        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2)
194
195    def test_oldargs0_2_kw(self):
196        msg = r"keys\(\) takes no keyword arguments"
197        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2)
198
199    def test_oldargs1_0(self):
200        msg = r"count\(\) takes exactly one argument \(0 given\)"
201        self.assertRaisesRegex(TypeError, msg, [].count)
202
203    def test_oldargs1_2(self):
204        msg = r"count\(\) takes exactly one argument \(2 given\)"
205        self.assertRaisesRegex(TypeError, msg, [].count, 1, 2)
206
207    def test_oldargs1_0_kw(self):
208        msg = r"count\(\) takes no keyword arguments"
209        self.assertRaisesRegex(TypeError, msg, [].count, x=2)
210
211    def test_oldargs1_1_kw(self):
212        msg = r"count\(\) takes no keyword arguments"
213        self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2)
214
215    def test_oldargs1_2_kw(self):
216        msg = r"count\(\) takes no keyword arguments"
217        self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2)
218
219    def test_object_not_callable(self):
220        msg = r"^'object' object is not callable$"
221        self.assertRaisesRegex(TypeError, msg, object())
222
223    def test_module_not_callable_no_suggestion_0(self):
224        msg = r"^'module' object is not callable$"
225        self.assertRaisesRegex(TypeError, msg, types.ModuleType("mod"))
226
227    def test_module_not_callable_no_suggestion_1(self):
228        msg = r"^'module' object is not callable$"
229        mod = types.ModuleType("mod")
230        mod.mod = 42
231        self.assertRaisesRegex(TypeError, msg, mod)
232
233    def test_module_not_callable_no_suggestion_2(self):
234        msg = r"^'module' object is not callable$"
235        mod = types.ModuleType("mod")
236        del mod.__name__
237        self.assertRaisesRegex(TypeError, msg, mod)
238
239    def test_module_not_callable_no_suggestion_3(self):
240        msg = r"^'module' object is not callable$"
241        mod = types.ModuleType("mod")
242        mod.__name__ = 42
243        self.assertRaisesRegex(TypeError, msg, mod)
244
245    def test_module_not_callable_suggestion(self):
246        msg = r"^'module' object is not callable\. Did you mean: 'mod\.mod\(\.\.\.\)'\?$"
247        mod = types.ModuleType("mod")
248        mod.mod = lambda: ...
249        self.assertRaisesRegex(TypeError, msg, mod)
250
251
252@unittest.skipIf(_testcapi is None, "requires _testcapi")
253class TestCallingConventions(unittest.TestCase):
254    """Test calling using various C calling conventions (METH_*) from Python
255
256    Subclasses test several kinds of functions (module-level, methods,
257    class methods static methods) using these attributes:
258      obj: the object that contains tested functions (as attributes)
259      expected_self: expected "self" argument to the C function
260
261    The base class tests module-level functions.
262    """
263
264    def setUp(self):
265        self.obj = self.expected_self = _testcapi
266
267    def test_varargs(self):
268        self.assertEqual(
269            self.obj.meth_varargs(1, 2, 3),
270            (self.expected_self, (1, 2, 3)),
271        )
272
273    def test_varargs_ext(self):
274        self.assertEqual(
275            self.obj.meth_varargs(*(1, 2, 3)),
276            (self.expected_self, (1, 2, 3)),
277        )
278
279    def test_varargs_error_kw(self):
280        msg = r"meth_varargs\(\) takes no keyword arguments"
281        self.assertRaisesRegex(
282            TypeError, msg, lambda: self.obj.meth_varargs(k=1),
283        )
284
285    def test_varargs_keywords(self):
286        self.assertEqual(
287            self.obj.meth_varargs_keywords(1, 2, a=3, b=4),
288            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
289        )
290
291    def test_varargs_keywords_ext(self):
292        self.assertEqual(
293            self.obj.meth_varargs_keywords(*[1, 2], **{'a': 3, 'b': 4}),
294            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
295        )
296
297    def test_o(self):
298        self.assertEqual(self.obj.meth_o(1), (self.expected_self, 1))
299
300    def test_o_ext(self):
301        self.assertEqual(self.obj.meth_o(*[1]), (self.expected_self, 1))
302
303    def test_o_error_no_arg(self):
304        msg = r"meth_o\(\) takes exactly one argument \(0 given\)"
305        self.assertRaisesRegex(TypeError, msg, self.obj.meth_o)
306
307    def test_o_error_two_args(self):
308        msg = r"meth_o\(\) takes exactly one argument \(2 given\)"
309        self.assertRaisesRegex(
310            TypeError, msg, lambda: self.obj.meth_o(1, 2),
311        )
312
313    def test_o_error_ext(self):
314        msg = r"meth_o\(\) takes exactly one argument \(3 given\)"
315        self.assertRaisesRegex(
316            TypeError, msg, lambda: self.obj.meth_o(*(1, 2, 3)),
317        )
318
319    def test_o_error_kw(self):
320        msg = r"meth_o\(\) takes no keyword arguments"
321        self.assertRaisesRegex(
322            TypeError, msg, lambda: self.obj.meth_o(k=1),
323        )
324
325    def test_o_error_arg_kw(self):
326        msg = r"meth_o\(\) takes no keyword arguments"
327        self.assertRaisesRegex(
328            TypeError, msg, lambda: self.obj.meth_o(k=1),
329        )
330
331    def test_noargs(self):
332        self.assertEqual(self.obj.meth_noargs(), self.expected_self)
333
334    def test_noargs_ext(self):
335        self.assertEqual(self.obj.meth_noargs(*[]), self.expected_self)
336
337    def test_noargs_error_arg(self):
338        msg = r"meth_noargs\(\) takes no arguments \(1 given\)"
339        self.assertRaisesRegex(
340            TypeError, msg, lambda: self.obj.meth_noargs(1),
341        )
342
343    def test_noargs_error_arg2(self):
344        msg = r"meth_noargs\(\) takes no arguments \(2 given\)"
345        self.assertRaisesRegex(
346            TypeError, msg, lambda: self.obj.meth_noargs(1, 2),
347        )
348
349    def test_noargs_error_ext(self):
350        msg = r"meth_noargs\(\) takes no arguments \(3 given\)"
351        self.assertRaisesRegex(
352            TypeError, msg, lambda: self.obj.meth_noargs(*(1, 2, 3)),
353        )
354
355    def test_noargs_error_kw(self):
356        msg = r"meth_noargs\(\) takes no keyword arguments"
357        self.assertRaisesRegex(
358            TypeError, msg, lambda: self.obj.meth_noargs(k=1),
359        )
360
361    def test_fastcall(self):
362        self.assertEqual(
363            self.obj.meth_fastcall(1, 2, 3),
364            (self.expected_self, (1, 2, 3)),
365        )
366
367    def test_fastcall_ext(self):
368        self.assertEqual(
369            self.obj.meth_fastcall(*(1, 2, 3)),
370            (self.expected_self, (1, 2, 3)),
371        )
372
373    def test_fastcall_error_kw(self):
374        msg = r"meth_fastcall\(\) takes no keyword arguments"
375        self.assertRaisesRegex(
376            TypeError, msg, lambda: self.obj.meth_fastcall(k=1),
377        )
378
379    def test_fastcall_keywords(self):
380        self.assertEqual(
381            self.obj.meth_fastcall_keywords(1, 2, a=3, b=4),
382            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
383        )
384
385    def test_fastcall_keywords_ext(self):
386        self.assertEqual(
387            self.obj.meth_fastcall_keywords(*(1, 2), **{'a': 3, 'b': 4}),
388            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
389        )
390
391
392class TestCallingConventionsInstance(TestCallingConventions):
393    """Test calling instance methods using various calling conventions"""
394
395    def setUp(self):
396        self.obj = self.expected_self = _testcapi.MethInstance()
397
398
399class TestCallingConventionsClass(TestCallingConventions):
400    """Test calling class methods using various calling conventions"""
401
402    def setUp(self):
403        self.obj = self.expected_self = _testcapi.MethClass
404
405
406class TestCallingConventionsClassInstance(TestCallingConventions):
407    """Test calling class methods on instance"""
408
409    def setUp(self):
410        self.obj = _testcapi.MethClass()
411        self.expected_self = _testcapi.MethClass
412
413
414class TestCallingConventionsStatic(TestCallingConventions):
415    """Test calling static methods using various calling conventions"""
416
417    def setUp(self):
418        self.obj = _testcapi.MethStatic()
419        self.expected_self = None
420
421
422def pyfunc(arg1, arg2):
423    return [arg1, arg2]
424
425
426def pyfunc_noarg():
427    return "noarg"
428
429
430class PythonClass:
431    def method(self, arg1, arg2):
432        return [arg1, arg2]
433
434    def method_noarg(self):
435        return "noarg"
436
437    @classmethod
438    def class_method(cls):
439        return "classmethod"
440
441    @staticmethod
442    def static_method():
443        return "staticmethod"
444
445
446PYTHON_INSTANCE = PythonClass()
447
448NULL_OR_EMPTY = object()
449
450
451class FastCallTests(unittest.TestCase):
452    """Test calling using various callables from C
453    """
454
455    # Test calls with positional arguments
456    CALLS_POSARGS = [
457        # (func, args: tuple, result)
458
459        # Python function with 2 arguments
460        (pyfunc, (1, 2), [1, 2]),
461
462        # Python function without argument
463        (pyfunc_noarg, (), "noarg"),
464
465        # Python class methods
466        (PythonClass.class_method, (), "classmethod"),
467        (PythonClass.static_method, (), "staticmethod"),
468
469        # Python instance methods
470        (PYTHON_INSTANCE.method, (1, 2), [1, 2]),
471        (PYTHON_INSTANCE.method_noarg, (), "noarg"),
472        (PYTHON_INSTANCE.class_method, (), "classmethod"),
473        (PYTHON_INSTANCE.static_method, (), "staticmethod"),
474
475        # C callables are added later
476    ]
477
478    # Test calls with positional and keyword arguments
479    CALLS_KWARGS = [
480        # (func, args: tuple, kwargs: dict, result)
481
482        # Python function with 2 arguments
483        (pyfunc, (1,), {'arg2': 2}, [1, 2]),
484        (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
485
486        # Python instance methods
487        (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]),
488        (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]),
489
490        # C callables are added later
491    ]
492
493    # Add all the calling conventions and variants of C callables
494    if _testcapi:
495        _instance = _testcapi.MethInstance()
496        for obj, expected_self in (
497            (_testcapi, _testcapi),  # module-level function
498            (_instance, _instance),  # bound method
499            (_testcapi.MethClass, _testcapi.MethClass),  # class method on class
500            (_testcapi.MethClass(), _testcapi.MethClass),  # class method on inst.
501            (_testcapi.MethStatic, None),  # static method
502        ):
503            CALLS_POSARGS.extend([
504                (obj.meth_varargs, (1, 2), (expected_self, (1, 2))),
505                (obj.meth_varargs_keywords,
506                    (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
507                (obj.meth_fastcall, (1, 2), (expected_self, (1, 2))),
508                (obj.meth_fastcall, (), (expected_self, ())),
509                (obj.meth_fastcall_keywords,
510                    (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
511                (obj.meth_fastcall_keywords,
512                    (), (expected_self, (), NULL_OR_EMPTY)),
513                (obj.meth_noargs, (), expected_self),
514                (obj.meth_o, (123, ), (expected_self, 123)),
515            ])
516
517            CALLS_KWARGS.extend([
518                (obj.meth_varargs_keywords,
519                    (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
520                (obj.meth_varargs_keywords,
521                    (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
522                (obj.meth_varargs_keywords,
523                    (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
524                (obj.meth_fastcall_keywords,
525                    (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
526                (obj.meth_fastcall_keywords,
527                    (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
528                (obj.meth_fastcall_keywords,
529                    (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
530            ])
531
532    def check_result(self, result, expected):
533        if isinstance(expected, tuple) and expected[-1] is NULL_OR_EMPTY:
534            if result[-1] in ({}, None):
535                expected = (*expected[:-1], result[-1])
536        self.assertEqual(result, expected)
537
538    @unittest.skipIf(_testcapi is None, "requires _testcapi")
539    def test_vectorcall_dict(self):
540        # Test PyObject_VectorcallDict()
541
542        for func, args, expected in self.CALLS_POSARGS:
543            with self.subTest(func=func, args=args):
544                # kwargs=NULL
545                result = _testcapi.pyobject_fastcalldict(func, args, None)
546                self.check_result(result, expected)
547
548                if not args:
549                    # args=NULL, nargs=0, kwargs=NULL
550                    result = _testcapi.pyobject_fastcalldict(func, None, None)
551                    self.check_result(result, expected)
552
553        for func, args, kwargs, expected in self.CALLS_KWARGS:
554            with self.subTest(func=func, args=args, kwargs=kwargs):
555                result = _testcapi.pyobject_fastcalldict(func, args, kwargs)
556                self.check_result(result, expected)
557
558    @unittest.skipIf(_testcapi is None, "requires _testcapi")
559    def test_vectorcall(self):
560        # Test PyObject_Vectorcall()
561
562        for func, args, expected in self.CALLS_POSARGS:
563            with self.subTest(func=func, args=args):
564                # kwnames=NULL
565                result = _testcapi.pyobject_vectorcall(func, args, None)
566                self.check_result(result, expected)
567
568                # kwnames=()
569                result = _testcapi.pyobject_vectorcall(func, args, ())
570                self.check_result(result, expected)
571
572                if not args:
573                    # kwnames=NULL
574                    result = _testcapi.pyobject_vectorcall(func, None, None)
575                    self.check_result(result, expected)
576
577                    # kwnames=()
578                    result = _testcapi.pyobject_vectorcall(func, None, ())
579                    self.check_result(result, expected)
580
581        for func, args, kwargs, expected in self.CALLS_KWARGS:
582            with self.subTest(func=func, args=args, kwargs=kwargs):
583                kwnames = tuple(kwargs.keys())
584                args = args + tuple(kwargs.values())
585                result = _testcapi.pyobject_vectorcall(func, args, kwnames)
586                self.check_result(result, expected)
587
588    def test_fastcall_clearing_dict(self):
589        # Test bpo-36907: the point of the test is just checking that this
590        # does not crash.
591        class IntWithDict:
592            __slots__ = ["kwargs"]
593            def __init__(self, **kwargs):
594                self.kwargs = kwargs
595            def __index__(self):
596                self.kwargs.clear()
597                gc.collect()
598                return 0
599        x = IntWithDict(optimize=IntWithDict())
600        # We test the argument handling of "compile" here, the compilation
601        # itself is not relevant. When we pass flags=x below, x.__index__() is
602        # called, which changes the keywords dict.
603        compile("pass", "", "exec", x, **x.kwargs)
604
605
606Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11
607Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17
608
609
610def testfunction(self):
611    """some doc"""
612    return self
613
614
615def testfunction_kw(self, *, kw):
616    """some doc"""
617    return self
618
619
620ADAPTIVE_WARMUP_DELAY = 2
621
622
623@unittest.skipIf(_testcapi is None, "requires _testcapi")
624class TestPEP590(unittest.TestCase):
625
626    def test_method_descriptor_flag(self):
627        import functools
628        cached = functools.lru_cache(1)(testfunction)
629
630        self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
631        self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
632        self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
633        self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
634        self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
635
636        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
637        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
638        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
639
640        # Mutable heap types should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR
641        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
642            pass
643        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
644
645    def test_vectorcall_flag(self):
646        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
647        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
648        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
649        self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
650
651        # Mutable heap types should inherit Py_TPFLAGS_HAVE_VECTORCALL,
652        # but should lose it when __call__ is overridden
653        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
654            pass
655        self.assertTrue(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
656        MethodDescriptorHeap.__call__ = print
657        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
658
659        # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL if
660        # they define __call__ directly
661        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
662            def __call__(self):
663                pass
664        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
665
666    def test_vectorcall_override(self):
667        # Check that tp_call can correctly override vectorcall.
668        # MethodDescriptorNopGet implements tp_call but it inherits from
669        # MethodDescriptorBase, which implements vectorcall. Since
670        # MethodDescriptorNopGet returns the args tuple when called, we check
671        # additionally that no new tuple is created for this call.
672        args = tuple(range(5))
673        f = _testcapi.MethodDescriptorNopGet()
674        self.assertIs(f(*args), args)
675
676    def test_vectorcall_override_on_mutable_class(self):
677        """Setting __call__ should disable vectorcall"""
678        TestType = _testcapi.make_vectorcall_class()
679        instance = TestType()
680        self.assertEqual(instance(), "tp_call")
681        instance.set_vectorcall(TestType)
682        self.assertEqual(instance(), "vectorcall")  # assume vectorcall is used
683        TestType.__call__ = lambda self: "custom"
684        self.assertEqual(instance(), "custom")
685
686    def test_vectorcall_override_with_subclass(self):
687        """Setting __call__ on a superclass should disable vectorcall"""
688        SuperType = _testcapi.make_vectorcall_class()
689        class DerivedType(SuperType):
690            pass
691
692        instance = DerivedType()
693
694        # Derived types with its own vectorcall should be unaffected
695        UnaffectedType1 = _testcapi.make_vectorcall_class(DerivedType)
696        UnaffectedType2 = _testcapi.make_vectorcall_class(SuperType)
697
698        # Aside: Quickly check that the C helper actually made derived types
699        self.assertTrue(issubclass(UnaffectedType1, DerivedType))
700        self.assertTrue(issubclass(UnaffectedType2, SuperType))
701
702        # Initial state: tp_call
703        self.assertEqual(instance(), "tp_call")
704        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True)
705        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True)
706        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
707        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)
708
709        # Setting the vectorcall function
710        instance.set_vectorcall(SuperType)
711
712        self.assertEqual(instance(), "vectorcall")
713        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True)
714        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True)
715        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
716        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)
717
718        # Setting __call__ should remove vectorcall from all subclasses
719        SuperType.__call__ = lambda self: "custom"
720
721        self.assertEqual(instance(), "custom")
722        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), False)
723        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), False)
724        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
725        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)
726
727
728    def test_vectorcall(self):
729        # Test a bunch of different ways to call objects:
730        # 1. vectorcall using PyVectorcall_Call()
731        #   (only for objects that support vectorcall directly)
732        # 2. normal call
733        # 3. vectorcall using PyObject_Vectorcall()
734        # 4. call as bound method
735        # 5. call using functools.partial
736
737        # A list of (function, args, kwargs, result) calls to test
738        calls = [(len, (range(42),), {}, 42),
739                 (list.append, ([], 0), {}, None),
740                 ([].append, (0,), {}, None),
741                 (sum, ([36],), {"start":6}, 42),
742                 (testfunction, (42,), {}, 42),
743                 (testfunction_kw, (42,), {"kw":None}, 42),
744                 (_testcapi.MethodDescriptorBase(), (0,), {}, True),
745                 (_testcapi.MethodDescriptorDerived(), (0,), {}, True),
746                 (_testcapi.MethodDescriptor2(), (0,), {}, False)]
747
748        from _testcapi import pyobject_vectorcall, pyvectorcall_call
749        from types import MethodType
750        from functools import partial
751
752        def vectorcall(func, args, kwargs):
753            args = *args, *kwargs.values()
754            kwnames = tuple(kwargs)
755            return pyobject_vectorcall(func, args, kwnames)
756
757        for (func, args, kwargs, expected) in calls:
758            with self.subTest(str(func)):
759                if not kwargs:
760                    self.assertEqual(expected, pyvectorcall_call(func, args))
761                self.assertEqual(expected, pyvectorcall_call(func, args, kwargs))
762
763        # Add derived classes (which do not support vectorcall directly,
764        # but do support all other ways of calling).
765
766        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
767            pass
768
769        class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase):
770            def __call__(self, n):
771                return 'new'
772
773        class SuperBase:
774            def __call__(self, *args):
775                return super().__call__(*args)
776
777        class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase):
778            def __call__(self, *args):
779                return super().__call__(*args)
780
781        calls += [
782            (dict.update, ({},), {"key":True}, None),
783            ({}.update, ({},), {"key":True}, None),
784            (MethodDescriptorHeap(), (0,), {}, True),
785            (MethodDescriptorOverridden(), (0,), {}, 'new'),
786            (MethodDescriptorSuper(), (0,), {}, True),
787        ]
788
789        for (func, args, kwargs, expected) in calls:
790            with self.subTest(str(func)):
791                args1 = args[1:]
792                meth = MethodType(func, args[0])
793                wrapped = partial(func)
794                if not kwargs:
795                    self.assertEqual(expected, func(*args))
796                    self.assertEqual(expected, pyobject_vectorcall(func, args, None))
797                    self.assertEqual(expected, meth(*args1))
798                    self.assertEqual(expected, wrapped(*args))
799                self.assertEqual(expected, func(*args, **kwargs))
800                self.assertEqual(expected, vectorcall(func, args, kwargs))
801                self.assertEqual(expected, meth(*args1, **kwargs))
802                self.assertEqual(expected, wrapped(*args, **kwargs))
803
804    def test_setvectorcall(self):
805        from _testcapi import function_setvectorcall
806        def f(num): return num + 1
807        assert_equal = self.assertEqual
808        num = 10
809        assert_equal(11, f(num))
810        function_setvectorcall(f)
811        # make sure specializer is triggered by running > 50 times
812        for _ in range(10 * ADAPTIVE_WARMUP_DELAY):
813            assert_equal("overridden", f(num))
814
815    def test_setvectorcall_load_attr_specialization_skip(self):
816        from _testcapi import function_setvectorcall
817
818        class X:
819            def __getattribute__(self, attr):
820                return attr
821
822        assert_equal = self.assertEqual
823        x = X()
824        assert_equal("a", x.a)
825        function_setvectorcall(X.__getattribute__)
826        # make sure specialization doesn't trigger
827        # when vectorcall is overridden
828        for _ in range(ADAPTIVE_WARMUP_DELAY):
829            assert_equal("overridden", x.a)
830
831    def test_setvectorcall_load_attr_specialization_deopt(self):
832        from _testcapi import function_setvectorcall
833
834        class X:
835            def __getattribute__(self, attr):
836                return attr
837
838        def get_a(x):
839            return x.a
840
841        assert_equal = self.assertEqual
842        x = X()
843        # trigger LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN specialization
844        for _ in range(ADAPTIVE_WARMUP_DELAY):
845            assert_equal("a", get_a(x))
846        function_setvectorcall(X.__getattribute__)
847        # make sure specialized LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
848        # gets deopted due to overridden vectorcall
849        for _ in range(ADAPTIVE_WARMUP_DELAY):
850            assert_equal("overridden", get_a(x))
851
852    @requires_limited_api
853    def test_vectorcall_limited_incoming(self):
854        from _testcapi import pyobject_vectorcall
855        obj = _testlimitedcapi.LimitedVectorCallClass()
856        self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called")
857
858    @requires_limited_api
859    def test_vectorcall_limited_outgoing(self):
860        from _testlimitedcapi import call_vectorcall
861
862        args_captured = []
863        kwargs_captured = []
864
865        def f(*args, **kwargs):
866            args_captured.append(args)
867            kwargs_captured.append(kwargs)
868            return "success"
869
870        self.assertEqual(call_vectorcall(f), "success")
871        self.assertEqual(args_captured, [("foo",)])
872        self.assertEqual(kwargs_captured, [{"baz": "bar"}])
873
874    @requires_limited_api
875    def test_vectorcall_limited_outgoing_method(self):
876        from _testlimitedcapi import call_vectorcall_method
877
878        args_captured = []
879        kwargs_captured = []
880
881        class TestInstance:
882            def f(self, *args, **kwargs):
883                args_captured.append(args)
884                kwargs_captured.append(kwargs)
885                return "success"
886
887        self.assertEqual(call_vectorcall_method(TestInstance()), "success")
888        self.assertEqual(args_captured, [("foo",)])
889        self.assertEqual(kwargs_captured, [{"baz": "bar"}])
890
891class A:
892    def method_two_args(self, x, y):
893        pass
894
895    @staticmethod
896    def static_no_args():
897        pass
898
899    @staticmethod
900    def positional_only(arg, /):
901        pass
902
903@cpython_only
904class TestErrorMessagesUseQualifiedName(unittest.TestCase):
905
906    @contextlib.contextmanager
907    def check_raises_type_error(self, message):
908        with self.assertRaises(TypeError) as cm:
909            yield
910        self.assertEqual(str(cm.exception), message)
911
912    def test_missing_arguments(self):
913        msg = "A.method_two_args() missing 1 required positional argument: 'y'"
914        with self.check_raises_type_error(msg):
915            A().method_two_args("x")
916
917    def test_too_many_positional(self):
918        msg = "A.static_no_args() takes 0 positional arguments but 1 was given"
919        with self.check_raises_type_error(msg):
920            A.static_no_args("oops it's an arg")
921
922    def test_positional_only_passed_as_keyword(self):
923        msg = "A.positional_only() got some positional-only arguments passed as keyword arguments: 'arg'"
924        with self.check_raises_type_error(msg):
925            A.positional_only(arg="x")
926
927    def test_unexpected_keyword(self):
928        msg = "A.method_two_args() got an unexpected keyword argument 'bad'"
929        with self.check_raises_type_error(msg):
930            A().method_two_args(bad="x")
931
932    def test_multiple_values(self):
933        msg = "A.method_two_args() got multiple values for argument 'x'"
934        with self.check_raises_type_error(msg):
935            A().method_two_args("x", "y", x="oops")
936
937@cpython_only
938class TestErrorMessagesSuggestions(unittest.TestCase):
939    @contextlib.contextmanager
940    def check_suggestion_includes(self, message):
941        with self.assertRaises(TypeError) as cm:
942            yield
943        self.assertIn(f"Did you mean '{message}'?", str(cm.exception))
944
945    @contextlib.contextmanager
946    def check_suggestion_not_present(self):
947        with self.assertRaises(TypeError) as cm:
948            yield
949        self.assertNotIn("Did you mean", str(cm.exception))
950
951    def test_unexpected_keyword_suggestion_valid_positions(self):
952        def foo(blech=None, /, aaa=None, *args, late1=None):
953            pass
954
955        cases = [
956            ("blach", None),
957            ("aa", "aaa"),
958            ("orgs", None),
959            ("late11", "late1"),
960        ]
961
962        for keyword, suggestion in cases:
963            with self.subTest(keyword):
964                ctx = self.check_suggestion_includes(suggestion) if suggestion else self.check_suggestion_not_present()
965                with ctx:
966                    foo(**{keyword:None})
967
968    def test_unexpected_keyword_suggestion_kinds(self):
969
970        def substitution(noise=None, more_noise=None, a = None, blech = None):
971            pass
972
973        def elimination(noise = None, more_noise = None, a = None, blch = None):
974            pass
975
976        def addition(noise = None, more_noise = None, a = None, bluchin = None):
977            pass
978
979        def substitution_over_elimination(blach = None, bluc = None):
980            pass
981
982        def substitution_over_addition(blach = None, bluchi = None):
983            pass
984
985        def elimination_over_addition(bluc = None, blucha = None):
986            pass
987
988        def case_change_over_substitution(BLuch=None, Luch = None, fluch = None):
989            pass
990
991        for func, suggestion in [
992            (addition, "bluchin"),
993            (substitution, "blech"),
994            (elimination, "blch"),
995            (addition, "bluchin"),
996            (substitution_over_elimination, "blach"),
997            (substitution_over_addition, "blach"),
998            (elimination_over_addition, "bluc"),
999            (case_change_over_substitution, "BLuch"),
1000        ]:
1001            with self.subTest(suggestion):
1002                with self.check_suggestion_includes(suggestion):
1003                    func(bluch=None)
1004
1005    def test_unexpected_keyword_suggestion_via_getargs(self):
1006        with self.check_suggestion_includes("maxsplit"):
1007            "foo".split(maxsplt=1)
1008
1009        self.assertRaisesRegex(
1010            TypeError, r"split\(\) got an unexpected keyword argument 'blech'$",
1011            "foo".split, blech=1
1012        )
1013        with self.check_suggestion_not_present():
1014            "foo".split(blech=1)
1015        with self.check_suggestion_not_present():
1016            "foo".split(more_noise=1, maxsplt=1)
1017
1018        # Also test the vgetargskeywords path
1019        with self.check_suggestion_includes("name"):
1020            ImportError(namez="oops")
1021
1022        self.assertRaisesRegex(
1023            TypeError, r"ImportError\(\) got an unexpected keyword argument 'blech'$",
1024            ImportError, blech=1
1025        )
1026        with self.check_suggestion_not_present():
1027            ImportError(blech=1)
1028        with self.check_suggestion_not_present():
1029            ImportError(blech=1, namez="oops")
1030
1031@cpython_only
1032class TestRecursion(unittest.TestCase):
1033
1034    @skip_on_s390x
1035    @unittest.skipIf(is_wasi and Py_DEBUG, "requires deep stack")
1036    @unittest.skipIf(_testcapi is None, "requires _testcapi")
1037    def test_super_deep(self):
1038
1039        def recurse(n):
1040            if n:
1041                recurse(n-1)
1042
1043        def py_recurse(n, m):
1044            if n:
1045                py_recurse(n-1, m)
1046            else:
1047                c_py_recurse(m-1)
1048
1049        def c_recurse(n):
1050            if n:
1051                _testcapi.pyobject_vectorcall(c_recurse, (n-1,), ())
1052
1053        def c_py_recurse(m):
1054            if m:
1055                _testcapi.pyobject_vectorcall(py_recurse, (1000, m), ())
1056
1057        with set_recursion_limit(100_000):
1058            recurse(90_000)
1059            with self.assertRaises(RecursionError):
1060                recurse(101_000)
1061            c_recurse(100)
1062            with self.assertRaises(RecursionError):
1063                c_recurse(90_000)
1064            c_py_recurse(90)
1065            with self.assertRaises(RecursionError):
1066                c_py_recurse(100_000)
1067
1068
1069class TestFunctionWithManyArgs(unittest.TestCase):
1070    def test_function_with_many_args(self):
1071        for N in (10, 500, 1000):
1072            with self.subTest(N=N):
1073                args = ",".join([f"a{i}" for i in range(N)])
1074                src = f"def f({args}) : return a{N//2}"
1075                l = {}
1076                exec(src, {}, l)
1077                self.assertEqual(l['f'](*range(N)), N//2)
1078
1079
1080@unittest.skipIf(_testcapi is None, 'need _testcapi')
1081class TestCAPI(unittest.TestCase):
1082    def test_cfunction_call(self):
1083        def func(*args, **kwargs):
1084            return (args, kwargs)
1085
1086        # PyCFunction_Call() was removed in Python 3.13 API, but was kept in
1087        # the stable ABI.
1088        def PyCFunction_Call(func, *args, **kwargs):
1089            if kwargs:
1090                return _testcapi.pycfunction_call(func, args, kwargs)
1091            else:
1092                return _testcapi.pycfunction_call(func, args)
1093
1094        self.assertEqual(PyCFunction_Call(func), ((), {}))
1095        self.assertEqual(PyCFunction_Call(func, 1, 2, 3), ((1, 2, 3), {}))
1096        self.assertEqual(PyCFunction_Call(func, "arg", num=5), (("arg",), {'num': 5}))
1097
1098
1099if __name__ == "__main__":
1100    unittest.main()
1101