guaranteed different hash bpo34320 kwargs should preserve order of passed ordereddict gh93252 stuff blows up if we don t pop the new frame after recovering from failed calls boom pyargunpackkeywordswithvararg pyargunpackkeywords test calling using various c calling conventions meth from python subclasses test several kinds of functions modulelevel methods class methods static methods using these attributes obj the object that contains tested functions as attributes expectedself expected self argument to the c function the base class tests modulelevel functions test calling instance methods using various calling conventions def setupself self obj self expectedself testcapi methinstance class testcallingconventionsclasstestcallingconventions test calling class methods on instance def setupself self obj testcapi methclass self expectedself testcapi methclass class testcallingconventionsstatictestcallingconventions test calling using various callables from c test calls with positional arguments func args tuple result python function with 2 arguments python function without argument python class methods python instance methods c callables are added later test calls with positional and keyword arguments func args tuple kwargs dict result python function with 2 arguments python instance methods c callables are added later add all the calling conventions and variants of c callables test pyobjectvectorcalldict kwargsnull argsnull nargs0 kwargsnull test pyobjectvectorcall kwnamesnull kwnames kwnamesnull kwnames test bpo36907 the point of the test is just checking that this does not crash we test the argument handling of compile here the compilation itself is not relevant when we pass flagsx below x index is called which changes the keywords dict some doc return self def testfunctionkwself kw mutable heap types should not inherit pytpflagsmethoddescriptor mutable heap types should inherit pytpflagshavevectorcall but should lose it when call is overridden mutable heap types should not inherit pytpflagshavevectorcall if they define call directly check that tpcall can correctly override vectorcall methoddescriptornopget implements tpcall but it inherits from methoddescriptorbase which implements vectorcall since methoddescriptornopget returns the args tuple when called we check additionally that no new tuple is created for this call setting call should disable vectorcall testtype testcapi makevectorcallclass instance testtype self assertequalinstance tpcall instance setvectorcalltesttype self assertequalinstance vectorcall assume vectorcall is used testtype call lambda self custom self assertequalinstance custom def testvectorcalloverridewithsubclassself derived types with its own vectorcall should be unaffected aside quickly check that the c helper actually made derived types initial state tpcall setting the vectorcall function setting call should remove vectorcall from all subclasses test a bunch of different ways to call objects 1 vectorcall using pyvectorcallcall only for objects that support vectorcall directly 2 normal call 3 vectorcall using pyobjectvectorcall 4 call as bound method 5 call using functools partial a list of function args kwargs result calls to test add derived classes which do not support vectorcall directly but do support all other ways of calling make sure specializer is triggered by running 50 times make sure specialization doesn t trigger when vectorcall is overridden trigger loadattrgetattributeoverridden specialization make sure specialized loadattrgetattributeoverridden gets deopted due to overridden vectorcall pycfunctioncall was removed in python 3 13 api but was kept in the stable abi guaranteed different hash bpo 34320 kwargs should preserve order of passed ordereddict gh 93252 stuff blows up if we don t pop the new frame after recovering from failed calls boom _pyarg_unpackkeywordswithvararg _pyarg_unpackkeywords test calling using various c calling conventions meth_ from python subclasses test several kinds of functions module level methods class methods static methods using these attributes obj the object that contains tested functions as attributes expected_self expected self argument to the c function the base class tests module level functions test calling instance methods using various calling conventions test calling class methods using various calling conventions test calling class methods on instance test calling static methods using various calling conventions test calling using various callables from c test calls with positional arguments func args tuple result python function with 2 arguments python function without argument python class methods python instance methods c callables are added later test calls with positional and keyword arguments func args tuple kwargs dict result python function with 2 arguments python instance methods c callables are added later add all the calling conventions and variants of c callables module level function bound method class method on class class method on inst static method test pyobject_vectorcalldict kwargs null args null nargs 0 kwargs null test pyobject_vectorcall kwnames null kwnames kwnames null kwnames test bpo 36907 the point of the test is just checking that this does not crash we test the argument handling of compile here the compilation itself is not relevant when we pass flags x below x __index__ is called which changes the keywords dict some doc some doc mutable heap types should not inherit py_tpflags_method_descriptor mutable heap types should inherit py_tpflags_have_vectorcall but should lose it when __call__ is overridden mutable heap types should not inherit py_tpflags_have_vectorcall if they define __call__ directly check that tp_call can correctly override vectorcall methoddescriptornopget implements tp_call but it inherits from methoddescriptorbase which implements vectorcall since methoddescriptornopget returns the args tuple when called we check additionally that no new tuple is created for this call setting __call__ should disable vectorcall assume vectorcall is used setting __call__ on a superclass should disable vectorcall derived types with its own vectorcall should be unaffected aside quickly check that the c helper actually made derived types initial state tp_call setting the vectorcall function setting __call__ should remove vectorcall from all subclasses test a bunch of different ways to call objects 1 vectorcall using pyvectorcall_call only for objects that support vectorcall directly 2 normal call 3 vectorcall using pyobject_vectorcall 4 call as bound method 5 call using functools partial a list of function args kwargs result calls to test add derived classes which do not support vectorcall directly but do support all other ways of calling make sure specializer is triggered by running 50 times make sure specialization doesn t trigger when vectorcall is overridden trigger load_attr_getattribute_overridden specialization make sure specialized load_attr_getattribute_overridden gets deopted due to overridden vectorcall pycfunction_call was removed in python 3 13 api but was kept in the stable abi
import unittest
from test.support import cpython_only, requires_limited_api, skip_on_s390x
try:
    import _testcapi
except ImportError:
    _testcapi = None
import struct
import collections
import itertools
import gc
import contextlib
import sys
import types


class BadStr(str):
    def __eq__(self, other):
        return True
    def __hash__(self):
        
        return str.__hash__(self) ^ 3


class FunctionCalls(unittest.TestCase):

    def test_kwargs_order(self):
        
        od = collections.OrderedDict([('a', 1), ('b', 2)])
        od.move_to_end('a')
        expected = list(od.items())

        def fn(**kw):
            return kw

        res = fn(**od)
        self.assertIsInstance(res, dict)
        self.assertEqual(list(res.items()), expected)

    def test_frames_are_popped_after_failed_calls(self):
        
        
        def f():
            pass
        for _ in range(1000):
            try:
                f(None)
            except TypeError:
                pass
        


@cpython_only
class CFunctionCallsErrorMessages(unittest.TestCase):

    def test_varargs0(self):
        msg = r"__contains__\(\) takes exactly one argument \(0 given\)"
        self.assertRaisesRegex(TypeError, msg, {}.__contains__)

    def test_varargs2(self):
        msg = r"__contains__\(\) takes exactly one argument \(2 given\)"
        self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1)

    def test_varargs3(self):
        msg = r"^from_bytes\(\) takes at most 2 positional arguments \(3 given\)"
        self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False)

    def test_varargs1min(self):
        msg = (r"get\(\) takes at least 1 argument \(0 given\)|"
               r"get expected at least 1 argument, got 0")
        self.assertRaisesRegex(TypeError, msg, {}.get)

        msg = r"expected 1 argument, got 0"
        self.assertRaisesRegex(TypeError, msg, {}.__delattr__)

    def test_varargs2min(self):
        msg = r"getattr expected at least 2 arguments, got 0"
        self.assertRaisesRegex(TypeError, msg, getattr)

    def test_varargs1max(self):
        msg = (r"input\(\) takes at most 1 argument \(2 given\)|"
               r"input expected at most 1 argument, got 2")
        self.assertRaisesRegex(TypeError, msg, input, 1, 2)

    def test_varargs2max(self):
        msg = (r"get\(\) takes at most 2 arguments \(3 given\)|"
               r"get expected at most 2 arguments, got 3")
        self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3)

    def test_varargs1_kw(self):
        msg = r"__contains__\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2)

    def test_varargs2_kw(self):
        msg = r"__contains__\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2)

    def test_varargs3_kw(self):
        msg = r"bool\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, bool, x=2)

    def test_varargs4_kw(self):
        msg = r"^(list[.])?index\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, [].index, x=2)

    def test_varargs5_kw(self):
        msg = r"^hasattr\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, hasattr, x=2)

    def test_varargs6_kw(self):
        msg = r"^getattr\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, getattr, x=2)

    def test_varargs7_kw(self):
        msg = r"^next\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, next, x=2)

    def test_varargs8_kw(self):
        msg = r"^_struct[.]pack\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)

    def test_varargs9_kw(self):
        msg = r"^_struct[.]pack_into\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)

    def test_varargs10_kw(self):
        msg = r"^deque[.]index\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)

    def test_varargs11_kw(self):
        msg = r"^Struct[.]pack\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)

    def test_varargs12_kw(self):
        msg = r"^staticmethod\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, staticmethod, func=id)

    def test_varargs13_kw(self):
        msg = r"^classmethod\(\) takes no keyword arguments$"
        self.assertRaisesRegex(TypeError, msg, classmethod, func=id)

    def test_varargs14_kw(self):
        msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$"
        self.assertRaisesRegex(TypeError, msg,
                               itertools.product, 0, repeat=1, foo=2)

    def test_varargs15_kw(self):
        msg = r"^ImportError\(\) takes at most 3 keyword arguments \(4 given\)$"
        self.assertRaisesRegex(TypeError, msg,
                               ImportError, 0, name=1, path=2, name_from=3, foo=3)

    def test_varargs16_kw(self):
        msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$"
        self.assertRaisesRegex(TypeError, msg,
                               min, 0, default=1, key=2, foo=3)

    def test_varargs17_kw(self):
        msg = r"'foo' is an invalid keyword argument for print\(\)$"
        self.assertRaisesRegex(TypeError, msg,
                               print, 0, sep=1, end=2, file=3, flush=4, foo=5)

    def test_varargs18_kw(self):
        
        msg = r"invalid keyword argument for print\(\)$"
        with self.assertRaisesRegex(TypeError, msg):
            print(0, 1, **{BadStr('foo'): ','})

    def test_varargs19_kw(self):
        
        msg = r"invalid keyword argument for round\(\)$"
        with self.assertRaisesRegex(TypeError, msg):
            round(1.75, **{BadStr('foo'): 1})

    def test_oldargs0_1(self):
        msg = r"keys\(\) takes no arguments \(1 given\)"
        self.assertRaisesRegex(TypeError, msg, {}.keys, 0)

    def test_oldargs0_2(self):
        msg = r"keys\(\) takes no arguments \(2 given\)"
        self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1)

    def test_oldargs0_1_kw(self):
        msg = r"keys\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2)

    def test_oldargs0_2_kw(self):
        msg = r"keys\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2)

    def test_oldargs1_0(self):
        msg = r"count\(\) takes exactly one argument \(0 given\)"
        self.assertRaisesRegex(TypeError, msg, [].count)

    def test_oldargs1_2(self):
        msg = r"count\(\) takes exactly one argument \(2 given\)"
        self.assertRaisesRegex(TypeError, msg, [].count, 1, 2)

    def test_oldargs1_0_kw(self):
        msg = r"count\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, [].count, x=2)

    def test_oldargs1_1_kw(self):
        msg = r"count\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2)

    def test_oldargs1_2_kw(self):
        msg = r"count\(\) takes no keyword arguments"
        self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2)

    def test_object_not_callable(self):
        msg = r"^'object' object is not callable$"
        self.assertRaisesRegex(TypeError, msg, object())

    def test_module_not_callable_no_suggestion_0(self):
        msg = r"^'module' object is not callable$"
        self.assertRaisesRegex(TypeError, msg, types.ModuleType("mod"))

    def test_module_not_callable_no_suggestion_1(self):
        msg = r"^'module' object is not callable$"
        mod = types.ModuleType("mod")
        mod.mod = 42
        self.assertRaisesRegex(TypeError, msg, mod)

    def test_module_not_callable_no_suggestion_2(self):
        msg = r"^'module' object is not callable$"
        mod = types.ModuleType("mod")
        del mod.__name__
        self.assertRaisesRegex(TypeError, msg, mod)

    def test_module_not_callable_no_suggestion_3(self):
        msg = r"^'module' object is not callable$"
        mod = types.ModuleType("mod")
        mod.__name__ = 42
        self.assertRaisesRegex(TypeError, msg, mod)

    def test_module_not_callable_suggestion(self):
        msg = r"^'module' object is not callable\. Did you mean: 'mod\.mod\(\.\.\.\)'\?$"
        mod = types.ModuleType("mod")
        mod.mod = lambda: ...
        self.assertRaisesRegex(TypeError, msg, mod)


class TestCallingConventions(unittest.TestCase):
    

    def setUp(self):
        self.obj = self.expected_self = _testcapi

    def test_varargs(self):
        self.assertEqual(
            self.obj.meth_varargs(1, 2, 3),
            (self.expected_self, (1, 2, 3)),
        )

    def test_varargs_ext(self):
        self.assertEqual(
            self.obj.meth_varargs(*(1, 2, 3)),
            (self.expected_self, (1, 2, 3)),
        )

    def test_varargs_error_kw(self):
        msg = r"meth_varargs\(\) takes no keyword arguments"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_varargs(k=1),
        )

    def test_varargs_keywords(self):
        self.assertEqual(
            self.obj.meth_varargs_keywords(1, 2, a=3, b=4),
            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
        )

    def test_varargs_keywords_ext(self):
        self.assertEqual(
            self.obj.meth_varargs_keywords(*[1, 2], **{'a': 3, 'b': 4}),
            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
        )

    def test_o(self):
        self.assertEqual(self.obj.meth_o(1), (self.expected_self, 1))

    def test_o_ext(self):
        self.assertEqual(self.obj.meth_o(*[1]), (self.expected_self, 1))

    def test_o_error_no_arg(self):
        msg = r"meth_o\(\) takes exactly one argument \(0 given\)"
        self.assertRaisesRegex(TypeError, msg, self.obj.meth_o)

    def test_o_error_two_args(self):
        msg = r"meth_o\(\) takes exactly one argument \(2 given\)"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_o(1, 2),
        )

    def test_o_error_ext(self):
        msg = r"meth_o\(\) takes exactly one argument \(3 given\)"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_o(*(1, 2, 3)),
        )

    def test_o_error_kw(self):
        msg = r"meth_o\(\) takes no keyword arguments"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_o(k=1),
        )

    def test_o_error_arg_kw(self):
        msg = r"meth_o\(\) takes no keyword arguments"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_o(k=1),
        )

    def test_noargs(self):
        self.assertEqual(self.obj.meth_noargs(), self.expected_self)

    def test_noargs_ext(self):
        self.assertEqual(self.obj.meth_noargs(*[]), self.expected_self)

    def test_noargs_error_arg(self):
        msg = r"meth_noargs\(\) takes no arguments \(1 given\)"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_noargs(1),
        )

    def test_noargs_error_arg2(self):
        msg = r"meth_noargs\(\) takes no arguments \(2 given\)"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_noargs(1, 2),
        )

    def test_noargs_error_ext(self):
        msg = r"meth_noargs\(\) takes no arguments \(3 given\)"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_noargs(*(1, 2, 3)),
        )

    def test_noargs_error_kw(self):
        msg = r"meth_noargs\(\) takes no keyword arguments"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_noargs(k=1),
        )

    def test_fastcall(self):
        self.assertEqual(
            self.obj.meth_fastcall(1, 2, 3),
            (self.expected_self, (1, 2, 3)),
        )

    def test_fastcall_ext(self):
        self.assertEqual(
            self.obj.meth_fastcall(*(1, 2, 3)),
            (self.expected_self, (1, 2, 3)),
        )

    def test_fastcall_error_kw(self):
        msg = r"meth_fastcall\(\) takes no keyword arguments"
        self.assertRaisesRegex(
            TypeError, msg, lambda: self.obj.meth_fastcall(k=1),
        )

    def test_fastcall_keywords(self):
        self.assertEqual(
            self.obj.meth_fastcall_keywords(1, 2, a=3, b=4),
            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
        )

    def test_fastcall_keywords_ext(self):
        self.assertEqual(
            self.obj.meth_fastcall_keywords(*(1, 2), **{'a': 3, 'b': 4}),
            (self.expected_self, (1, 2), {'a': 3, 'b': 4})
        )


class TestCallingConventionsInstance(TestCallingConventions):
    

    def setUp(self):
        self.obj = self.expected_self = _testcapi.MethInstance()


class TestCallingConventionsClass(TestCallingConventions):
    

    def setUp(self):
        self.obj = self.expected_self = _testcapi.MethClass


class TestCallingConventionsClassInstance(TestCallingConventions):
    

    def setUp(self):
        self.obj = _testcapi.MethClass()
        self.expected_self = _testcapi.MethClass


class TestCallingConventionsStatic(TestCallingConventions):
    

    def setUp(self):
        self.obj = _testcapi.MethStatic()
        self.expected_self = None


def pyfunc(arg1, arg2):
    return [arg1, arg2]


def pyfunc_noarg():
    return "noarg"


class PythonClass:
    def method(self, arg1, arg2):
        return [arg1, arg2]

    def method_noarg(self):
        return "noarg"

    @classmethod
    def class_method(cls):
        return "classmethod"

    @staticmethod
    def static_method():
        return "staticmethod"


PYTHON_INSTANCE = PythonClass()

NULL_OR_EMPTY = object()

class FastCallTests(unittest.TestCase):
    

    
    CALLS_POSARGS = [
        

        
        (pyfunc, (1, 2), [1, 2]),

        
        (pyfunc_noarg, (), "noarg"),

        
        (PythonClass.class_method, (), "classmethod"),
        (PythonClass.static_method, (), "staticmethod"),

        
        (PYTHON_INSTANCE.method, (1, 2), [1, 2]),
        (PYTHON_INSTANCE.method_noarg, (), "noarg"),
        (PYTHON_INSTANCE.class_method, (), "classmethod"),
        (PYTHON_INSTANCE.static_method, (), "staticmethod"),

        
    ]

    
    CALLS_KWARGS = [
        

        
        (pyfunc, (1,), {'arg2': 2}, [1, 2]),
        (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]),

        
        (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]),
        (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]),

        
    ]

    
    _instance = _testcapi.MethInstance()
    for obj, expected_self in (
        (_testcapi, _testcapi),  
        (_instance, _instance),  
        (_testcapi.MethClass, _testcapi.MethClass),  
        (_testcapi.MethClass(), _testcapi.MethClass),  
        (_testcapi.MethStatic, None),  
    ):
        CALLS_POSARGS.extend([
            (obj.meth_varargs, (1, 2), (expected_self, (1, 2))),
            (obj.meth_varargs_keywords,
                (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
            (obj.meth_fastcall, (1, 2), (expected_self, (1, 2))),
            (obj.meth_fastcall, (), (expected_self, ())),
            (obj.meth_fastcall_keywords,
                (1, 2), (expected_self, (1, 2), NULL_OR_EMPTY)),
            (obj.meth_fastcall_keywords,
                (), (expected_self, (), NULL_OR_EMPTY)),
            (obj.meth_noargs, (), expected_self),
            (obj.meth_o, (123, ), (expected_self, 123)),
        ])

        CALLS_KWARGS.extend([
            (obj.meth_varargs_keywords,
                (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
            (obj.meth_varargs_keywords,
                (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
            (obj.meth_varargs_keywords,
                (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
            (obj.meth_fastcall_keywords,
                (1, 2), {'x': 'y'}, (expected_self, (1, 2), {'x': 'y'})),
            (obj.meth_fastcall_keywords,
                (), {'x': 'y'}, (expected_self, (), {'x': 'y'})),
            (obj.meth_fastcall_keywords,
                (1, 2), {}, (expected_self, (1, 2), NULL_OR_EMPTY)),
        ])

    def check_result(self, result, expected):
        if isinstance(expected, tuple) and expected[-1] is NULL_OR_EMPTY:
            if result[-1] in ({}, None):
                expected = (*expected[:-1], result[-1])
        self.assertEqual(result, expected)

    def test_vectorcall_dict(self):
        

        for func, args, expected in self.CALLS_POSARGS:
            with self.subTest(func=func, args=args):
                
                result = _testcapi.pyobject_fastcalldict(func, args, None)
                self.check_result(result, expected)

                if not args:
                    
                    result = _testcapi.pyobject_fastcalldict(func, None, None)
                    self.check_result(result, expected)

        for func, args, kwargs, expected in self.CALLS_KWARGS:
            with self.subTest(func=func, args=args, kwargs=kwargs):
                result = _testcapi.pyobject_fastcalldict(func, args, kwargs)
                self.check_result(result, expected)

    def test_vectorcall(self):
        

        for func, args, expected in self.CALLS_POSARGS:
            with self.subTest(func=func, args=args):
                
                result = _testcapi.pyobject_vectorcall(func, args, None)
                self.check_result(result, expected)

                
                result = _testcapi.pyobject_vectorcall(func, args, ())
                self.check_result(result, expected)

                if not args:
                    
                    result = _testcapi.pyobject_vectorcall(func, None, None)
                    self.check_result(result, expected)

                    
                    result = _testcapi.pyobject_vectorcall(func, None, ())
                    self.check_result(result, expected)

        for func, args, kwargs, expected in self.CALLS_KWARGS:
            with self.subTest(func=func, args=args, kwargs=kwargs):
                kwnames = tuple(kwargs.keys())
                args = args + tuple(kwargs.values())
                result = _testcapi.pyobject_vectorcall(func, args, kwnames)
                self.check_result(result, expected)

    def test_fastcall_clearing_dict(self):
        
        
        class IntWithDict:
            __slots__ = ["kwargs"]
            def __init__(self, **kwargs):
                self.kwargs = kwargs
            def __index__(self):
                self.kwargs.clear()
                gc.collect()
                return 0
        x = IntWithDict(optimize=IntWithDict())
        
        
        
        compile("pass", "", "exec", x, **x.kwargs)


Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11
Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17


def testfunction(self):
    
    return self


def testfunction_kw(self, *, kw):
    
    return self


ADAPTIVE_WARMUP_DELAY = 2


class TestPEP590(unittest.TestCase):

    def test_method_descriptor_flag(self):
        import functools
        cached = functools.lru_cache(1)(testfunction)

        self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)

        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)
        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)

        
        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
            pass
        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR)

    def test_vectorcall_flag(self):
        self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
        self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
        self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
        self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)

        
        
        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
            pass
        self.assertTrue(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)
        MethodDescriptorHeap.__call__ = print
        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)

        
        
        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
            def __call__(self):
                pass
        self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL)

    def test_vectorcall_override(self):
        
        
        
        
        
        args = tuple(range(5))
        f = _testcapi.MethodDescriptorNopGet()
        self.assertIs(f(*args), args)

    def test_vectorcall_override_on_mutable_class(self):
        
        TestType = _testcapi.make_vectorcall_class()
        instance = TestType()
        self.assertEqual(instance(), "tp_call")
        instance.set_vectorcall(TestType)
        self.assertEqual(instance(), "vectorcall")  
        TestType.__call__ = lambda self: "custom"
        self.assertEqual(instance(), "custom")

    def test_vectorcall_override_with_subclass(self):
        
        SuperType = _testcapi.make_vectorcall_class()
        class DerivedType(SuperType):
            pass

        instance = DerivedType()

        
        UnaffectedType1 = _testcapi.make_vectorcall_class(DerivedType)
        UnaffectedType2 = _testcapi.make_vectorcall_class(SuperType)

        
        self.assertTrue(issubclass(UnaffectedType1, DerivedType))
        self.assertTrue(issubclass(UnaffectedType2, SuperType))

        
        self.assertEqual(instance(), "tp_call")
        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)

        
        instance.set_vectorcall(SuperType)

        self.assertEqual(instance(), "vectorcall")
        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)

        
        SuperType.__call__ = lambda self: "custom"

        self.assertEqual(instance(), "custom")
        self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), False)
        self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), False)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True)
        self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True)


    def test_vectorcall(self):
        
        
        
        
        
        
        

        
        calls = [(len, (range(42),), {}, 42),
                 (list.append, ([], 0), {}, None),
                 ([].append, (0,), {}, None),
                 (sum, ([36],), {"start":6}, 42),
                 (testfunction, (42,), {}, 42),
                 (testfunction_kw, (42,), {"kw":None}, 42),
                 (_testcapi.MethodDescriptorBase(), (0,), {}, True),
                 (_testcapi.MethodDescriptorDerived(), (0,), {}, True),
                 (_testcapi.MethodDescriptor2(), (0,), {}, False)]

        from _testcapi import pyobject_vectorcall, pyvectorcall_call
        from types import MethodType
        from functools import partial

        def vectorcall(func, args, kwargs):
            args = *args, *kwargs.values()
            kwnames = tuple(kwargs)
            return pyobject_vectorcall(func, args, kwnames)

        for (func, args, kwargs, expected) in calls:
            with self.subTest(str(func)):
                if not kwargs:
                    self.assertEqual(expected, pyvectorcall_call(func, args))
                self.assertEqual(expected, pyvectorcall_call(func, args, kwargs))

        
        

        class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
            pass

        class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase):
            def __call__(self, n):
                return 'new'

        class SuperBase:
            def __call__(self, *args):
                return super().__call__(*args)

        class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase):
            def __call__(self, *args):
                return super().__call__(*args)

        calls += [
            (dict.update, ({},), {"key":True}, None),
            ({}.update, ({},), {"key":True}, None),
            (MethodDescriptorHeap(), (0,), {}, True),
            (MethodDescriptorOverridden(), (0,), {}, 'new'),
            (MethodDescriptorSuper(), (0,), {}, True),
        ]

        for (func, args, kwargs, expected) in calls:
            with self.subTest(str(func)):
                args1 = args[1:]
                meth = MethodType(func, args[0])
                wrapped = partial(func)
                if not kwargs:
                    self.assertEqual(expected, func(*args))
                    self.assertEqual(expected, pyobject_vectorcall(func, args, None))
                    self.assertEqual(expected, meth(*args1))
                    self.assertEqual(expected, wrapped(*args))
                self.assertEqual(expected, func(*args, **kwargs))
                self.assertEqual(expected, vectorcall(func, args, kwargs))
                self.assertEqual(expected, meth(*args1, **kwargs))
                self.assertEqual(expected, wrapped(*args, **kwargs))

    def test_setvectorcall(self):
        from _testcapi import function_setvectorcall
        def f(num): return num + 1
        assert_equal = self.assertEqual
        num = 10
        assert_equal(11, f(num))
        function_setvectorcall(f)
        
        for _ in range(10 * ADAPTIVE_WARMUP_DELAY):
            assert_equal("overridden", f(num))

    def test_setvectorcall_load_attr_specialization_skip(self):
        from _testcapi import function_setvectorcall

        class X:
            def __getattribute__(self, attr):
                return attr

        assert_equal = self.assertEqual
        x = X()
        assert_equal("a", x.a)
        function_setvectorcall(X.__getattribute__)
        
        
        for _ in range(ADAPTIVE_WARMUP_DELAY):
            assert_equal("overridden", x.a)

    def test_setvectorcall_load_attr_specialization_deopt(self):
        from _testcapi import function_setvectorcall

        class X:
            def __getattribute__(self, attr):
                return attr

        def get_a(x):
            return x.a

        assert_equal = self.assertEqual
        x = X()
        
        for _ in range(ADAPTIVE_WARMUP_DELAY):
            assert_equal("a", get_a(x))
        function_setvectorcall(X.__getattribute__)
        
        
        for _ in range(ADAPTIVE_WARMUP_DELAY):
            assert_equal("overridden", get_a(x))

    @requires_limited_api
    def test_vectorcall_limited_incoming(self):
        from _testcapi import pyobject_vectorcall
        obj = _testcapi.LimitedVectorCallClass()
        self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called")

    @requires_limited_api
    def test_vectorcall_limited_outgoing(self):
        from _testcapi import call_vectorcall

        args_captured = []
        kwargs_captured = []

        def f(*args, **kwargs):
            args_captured.append(args)
            kwargs_captured.append(kwargs)
            return "success"

        self.assertEqual(call_vectorcall(f), "success")
        self.assertEqual(args_captured, [("foo",)])
        self.assertEqual(kwargs_captured, [{"baz": "bar"}])

    @requires_limited_api
    def test_vectorcall_limited_outgoing_method(self):
        from _testcapi import call_vectorcall_method

        args_captured = []
        kwargs_captured = []

        class TestInstance:
            def f(self, *args, **kwargs):
                args_captured.append(args)
                kwargs_captured.append(kwargs)
                return "success"

        self.assertEqual(call_vectorcall_method(TestInstance()), "success")
        self.assertEqual(args_captured, [("foo",)])
        self.assertEqual(kwargs_captured, [{"baz": "bar"}])

class A:
    def method_two_args(self, x, y):
        pass

    @staticmethod
    def static_no_args():
        pass

    @staticmethod
    def positional_only(arg, /):
        pass

@cpython_only
class TestErrorMessagesUseQualifiedName(unittest.TestCase):

    @contextlib.contextmanager
    def check_raises_type_error(self, message):
        with self.assertRaises(TypeError) as cm:
            yield
        self.assertEqual(str(cm.exception), message)

    def test_missing_arguments(self):
        msg = "A.method_two_args() missing 1 required positional argument: 'y'"
        with self.check_raises_type_error(msg):
            A().method_two_args("x")

    def test_too_many_positional(self):
        msg = "A.static_no_args() takes 0 positional arguments but 1 was given"
        with self.check_raises_type_error(msg):
            A.static_no_args("oops it's an arg")

    def test_positional_only_passed_as_keyword(self):
        msg = "A.positional_only() got some positional-only arguments passed as keyword arguments: 'arg'"
        with self.check_raises_type_error(msg):
            A.positional_only(arg="x")

    def test_unexpected_keyword(self):
        msg = "A.method_two_args() got an unexpected keyword argument 'bad'"
        with self.check_raises_type_error(msg):
            A().method_two_args(bad="x")

    def test_multiple_values(self):
        msg = "A.method_two_args() got multiple values for argument 'x'"
        with self.check_raises_type_error(msg):
            A().method_two_args("x", "y", x="oops")

@cpython_only
class TestErrorMessagesSuggestions(unittest.TestCase):
    @contextlib.contextmanager
    def check_suggestion_includes(self, message):
        with self.assertRaises(TypeError) as cm:
            yield
        self.assertIn(f"Did you mean '{message}'?", str(cm.exception))

    @contextlib.contextmanager
    def check_suggestion_not_pressent(self):
        with self.assertRaises(TypeError) as cm:
            yield
        self.assertNotIn("Did you mean", str(cm.exception))

    def test_unexpected_keyword_suggestion_valid_positions(self):
        def foo(blech=None, /, aaa=None, *args, late1=None):
            pass

        cases = [
            ("blach", None),
            ("aa", "aaa"),
            ("orgs", None),
            ("late11", "late1"),
        ]

        for keyword, suggestion in cases:
            with self.subTest(keyword):
                ctx = self.check_suggestion_includes(suggestion) if suggestion else self.check_suggestion_not_pressent()
                with ctx:
                    foo(**{keyword:None})

    def test_unexpected_keyword_suggestion_kinds(self):

        def substitution(noise=None, more_noise=None, a = None, blech = None):
            pass

        def elimination(noise = None, more_noise = None, a = None, blch = None):
            pass

        def addition(noise = None, more_noise = None, a = None, bluchin = None):
            pass

        def substitution_over_elimination(blach = None, bluc = None):
            pass

        def substitution_over_addition(blach = None, bluchi = None):
            pass

        def elimination_over_addition(bluc = None, blucha = None):
            pass

        def case_change_over_substitution(BLuch=None, Luch = None, fluch = None):
            pass

        for func, suggestion in [
            (addition, "bluchin"),
            (substitution, "blech"),
            (elimination, "blch"),
            (addition, "bluchin"),
            (substitution_over_elimination, "blach"),
            (substitution_over_addition, "blach"),
            (elimination_over_addition, "bluc"),
            (case_change_over_substitution, "BLuch"),
        ]:
            with self.subTest(suggestion):
                with self.check_suggestion_includes(suggestion):
                    func(bluch=None)

@cpython_only
class TestRecursion(unittest.TestCase):

    @skip_on_s390x
    def test_super_deep(self):

        def recurse(n):
            if n:
                recurse(n-1)

        def py_recurse(n, m):
            if n:
                py_recurse(n-1, m)
            else:
                c_py_recurse(m-1)

        def c_recurse(n):
            if n:
                _testcapi.pyobject_vectorcall(c_recurse, (n-1,), ())

        def c_py_recurse(m):
            if m:
                _testcapi.pyobject_vectorcall(py_recurse, (1000, m), ())

        depth = sys.getrecursionlimit()
        sys.setrecursionlimit(100_000)
        try:
            recurse(90_000)
            with self.assertRaises(RecursionError):
                recurse(101_000)
            c_recurse(100)
            with self.assertRaises(RecursionError):
                c_recurse(90_000)
            c_py_recurse(90)
            with self.assertRaises(RecursionError):
                c_py_recurse(100_000)
        finally:
            sys.setrecursionlimit(depth)


class TestFunctionWithManyArgs(unittest.TestCase):
    def test_function_with_many_args(self):
        for N in (10, 500, 1000):
            with self.subTest(N=N):
                args = ",".join([f"a{i}" for i in range(N)])
                src = f"def f({args}) : return a{N//2}"
                l = {}
                exec(src, {}, l)
                self.assertEqual(l['f'](*range(N)), N//2)


@unittest.skipIf(_testcapi is None, 'need _testcapi')
class TestCAPI(unittest.TestCase):
    def test_cfunction_call(self):
        def func(*args, **kwargs):
            return (args, kwargs)

        
        
        def PyCFunction_Call(func, *args, **kwargs):
            if kwargs:
                return _testcapi.pycfunction_call(func, args, kwargs)
            else:
                return _testcapi.pycfunction_call(func, args)

        self.assertEqual(PyCFunction_Call(func), ((), {}))
        self.assertEqual(PyCFunction_Call(func, 1, 2, 3), ((1, 2, 3), {}))
        self.assertEqual(PyCFunction_Call(func, "arg", num=5), (("arg",), {'num': 5}))


if __name__ == "__main__":
    unittest.main()