(root)/
Python-3.11.7/
Lib/
test/
test_call.py
       1  import unittest
       2  from test.support import cpython_only
       3  try:
       4      import _testcapi
       5  except ImportError:
       6      _testcapi = None
       7  import struct
       8  import collections
       9  import itertools
      10  import gc
      11  import contextlib
      12  
      13  
      14  class ESC[4;38;5;81mBadStr(ESC[4;38;5;149mstr):
      15      def __eq__(self, other):
      16          return True
      17      def __hash__(self):
      18          # Guaranteed different hash
      19          return str.__hash__(self) ^ 3
      20  
      21  
      22  class ESC[4;38;5;81mFunctionCalls(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      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
      51  class ESC[4;38;5;81mCFunctionCallsErrorMessages(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      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  
     206  class ESC[4;38;5;81mTestCallingConventions(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     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  
     345  class ESC[4;38;5;81mTestCallingConventionsInstance(ESC[4;38;5;149mTestCallingConventions):
     346      """Test calling instance methods using various calling conventions"""
     347  
     348      def setUp(self):
     349          self.obj = self.expected_self = _testcapi.MethInstance()
     350  
     351  
     352  class ESC[4;38;5;81mTestCallingConventionsClass(ESC[4;38;5;149mTestCallingConventions):
     353      """Test calling class methods using various calling conventions"""
     354  
     355      def setUp(self):
     356          self.obj = self.expected_self = _testcapi.MethClass
     357  
     358  
     359  class ESC[4;38;5;81mTestCallingConventionsClassInstance(ESC[4;38;5;149mTestCallingConventions):
     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  
     367  class ESC[4;38;5;81mTestCallingConventionsStatic(ESC[4;38;5;149mTestCallingConventions):
     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  
     375  def pyfunc(arg1, arg2):
     376      return [arg1, arg2]
     377  
     378  
     379  def pyfunc_noarg():
     380      return "noarg"
     381  
     382  
     383  class ESC[4;38;5;81mPythonClass:
     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  
     399  PYTHON_INSTANCE = PythonClass()
     400  
     401  NULL_OR_EMPTY = object()
     402  
     403  class ESC[4;38;5;81mFastCallTests(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     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 ESC[4;38;5;81mIntWithDict:
     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  
     568  Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11
     569  Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17
     570  
     571  
     572  def testfunction(self):
     573      """some doc"""
     574      return self
     575  
     576  
     577  def testfunction_kw(self, *, kw):
     578      """some doc"""
     579      return self
     580  
     581  
     582  class ESC[4;38;5;81mTestPEP590(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     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 ESC[4;38;5;81mMethodDescriptorHeap(ESC[4;38;5;149m_testcapiESC[4;38;5;149m.ESC[4;38;5;149mMethodDescriptorBase):
     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 ESC[4;38;5;81mMethodDescriptorHeap(ESC[4;38;5;149m_testcapiESC[4;38;5;149m.ESC[4;38;5;149mMethodDescriptorBase):
     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 ESC[4;38;5;81mMethodDescriptorHeap(ESC[4;38;5;149m_testcapiESC[4;38;5;149m.ESC[4;38;5;149mMethodDescriptorBase):
     663              pass
     664  
     665          class ESC[4;38;5;81mMethodDescriptorOverridden(ESC[4;38;5;149m_testcapiESC[4;38;5;149m.ESC[4;38;5;149mMethodDescriptorBase):
     666              def __call__(self, n):
     667                  return 'new'
     668  
     669          class ESC[4;38;5;81mSuperBase:
     670              def __call__(self, *args):
     671                  return super().__call__(*args)
     672  
     673          class ESC[4;38;5;81mMethodDescriptorSuper(ESC[4;38;5;149mSuperBase, ESC[4;38;5;149m_testcapiESC[4;38;5;149m.ESC[4;38;5;149mMethodDescriptorBase):
     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  
     701  class ESC[4;38;5;81mA:
     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
     714  class ESC[4;38;5;81mTestErrorMessagesUseQualifiedName(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     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  
     748  if __name__ == "__main__":
     749      unittest.main()