1import datetime 2import unittest 3from test.support import cpython_only 4try: 5 import _testcapi 6except ImportError: 7 _testcapi = None 8import struct 9import collections 10import itertools 11import gc 12 13 14class FunctionCalls(unittest.TestCase): 15 16 def test_kwargs_order(self): 17 # bpo-34320: **kwargs should preserve order of passed OrderedDict 18 od = collections.OrderedDict([('a', 1), ('b', 2)]) 19 od.move_to_end('a') 20 expected = list(od.items()) 21 22 def fn(**kw): 23 return kw 24 25 res = fn(**od) 26 self.assertIsInstance(res, dict) 27 self.assertEqual(list(res.items()), expected) 28 29 30# The test cases here cover several paths through the function calling 31# code. They depend on the METH_XXX flag that is used to define a C 32# function, which can't be verified from Python. If the METH_XXX decl 33# for a C function changes, these tests may not cover the right paths. 34 35class CFunctionCalls(unittest.TestCase): 36 37 def test_varargs0(self): 38 self.assertRaises(TypeError, {}.__contains__) 39 40 def test_varargs1(self): 41 {}.__contains__(0) 42 43 def test_varargs2(self): 44 self.assertRaises(TypeError, {}.__contains__, 0, 1) 45 46 def test_varargs0_ext(self): 47 try: 48 {}.__contains__(*()) 49 except TypeError: 50 pass 51 52 def test_varargs1_ext(self): 53 {}.__contains__(*(0,)) 54 55 def test_varargs2_ext(self): 56 try: 57 {}.__contains__(*(1, 2)) 58 except TypeError: 59 pass 60 else: 61 raise RuntimeError 62 63 def test_varargs1_kw(self): 64 self.assertRaises(TypeError, {}.__contains__, x=2) 65 66 def test_varargs2_kw(self): 67 self.assertRaises(TypeError, {}.__contains__, x=2, y=2) 68 69 def test_oldargs0_0(self): 70 {}.keys() 71 72 def test_oldargs0_1(self): 73 self.assertRaises(TypeError, {}.keys, 0) 74 75 def test_oldargs0_2(self): 76 self.assertRaises(TypeError, {}.keys, 0, 1) 77 78 def test_oldargs0_0_ext(self): 79 {}.keys(*()) 80 81 def test_oldargs0_1_ext(self): 82 try: 83 {}.keys(*(0,)) 84 except TypeError: 85 pass 86 else: 87 raise RuntimeError 88 89 def test_oldargs0_2_ext(self): 90 try: 91 {}.keys(*(1, 2)) 92 except TypeError: 93 pass 94 else: 95 raise RuntimeError 96 97 def test_oldargs0_0_kw(self): 98 try: 99 {}.keys(x=2) 100 except TypeError: 101 pass 102 else: 103 raise RuntimeError 104 105 def test_oldargs0_1_kw(self): 106 self.assertRaises(TypeError, {}.keys, x=2) 107 108 def test_oldargs0_2_kw(self): 109 self.assertRaises(TypeError, {}.keys, x=2, y=2) 110 111 def test_oldargs1_0(self): 112 self.assertRaises(TypeError, [].count) 113 114 def test_oldargs1_1(self): 115 [].count(1) 116 117 def test_oldargs1_2(self): 118 self.assertRaises(TypeError, [].count, 1, 2) 119 120 def test_oldargs1_0_ext(self): 121 try: 122 [].count(*()) 123 except TypeError: 124 pass 125 else: 126 raise RuntimeError 127 128 def test_oldargs1_1_ext(self): 129 [].count(*(1,)) 130 131 def test_oldargs1_2_ext(self): 132 try: 133 [].count(*(1, 2)) 134 except TypeError: 135 pass 136 else: 137 raise RuntimeError 138 139 def test_oldargs1_0_kw(self): 140 self.assertRaises(TypeError, [].count, x=2) 141 142 def test_oldargs1_1_kw(self): 143 self.assertRaises(TypeError, [].count, {}, x=2) 144 145 def test_oldargs1_2_kw(self): 146 self.assertRaises(TypeError, [].count, x=2, y=2) 147 148 149@cpython_only 150class CFunctionCallsErrorMessages(unittest.TestCase): 151 152 def test_varargs0(self): 153 msg = r"__contains__\(\) takes exactly one argument \(0 given\)" 154 self.assertRaisesRegex(TypeError, msg, {}.__contains__) 155 156 def test_varargs2(self): 157 msg = r"__contains__\(\) takes exactly one argument \(2 given\)" 158 self.assertRaisesRegex(TypeError, msg, {}.__contains__, 0, 1) 159 160 def test_varargs3(self): 161 msg = r"^from_bytes\(\) takes exactly 2 positional arguments \(3 given\)" 162 self.assertRaisesRegex(TypeError, msg, int.from_bytes, b'a', 'little', False) 163 164 def test_varargs1min(self): 165 msg = r"get expected at least 1 argument, got 0" 166 self.assertRaisesRegex(TypeError, msg, {}.get) 167 168 msg = r"expected 1 argument, got 0" 169 self.assertRaisesRegex(TypeError, msg, {}.__delattr__) 170 171 def test_varargs2min(self): 172 msg = r"getattr expected at least 2 arguments, got 0" 173 self.assertRaisesRegex(TypeError, msg, getattr) 174 175 def test_varargs1max(self): 176 msg = r"input expected at most 1 argument, got 2" 177 self.assertRaisesRegex(TypeError, msg, input, 1, 2) 178 179 def test_varargs2max(self): 180 msg = r"get expected at most 2 arguments, got 3" 181 self.assertRaisesRegex(TypeError, msg, {}.get, 1, 2, 3) 182 183 def test_varargs1_kw(self): 184 msg = r"__contains__\(\) takes no keyword arguments" 185 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2) 186 187 def test_varargs2_kw(self): 188 msg = r"__contains__\(\) takes no keyword arguments" 189 self.assertRaisesRegex(TypeError, msg, {}.__contains__, x=2, y=2) 190 191 def test_varargs3_kw(self): 192 msg = r"bool\(\) takes no keyword arguments" 193 self.assertRaisesRegex(TypeError, msg, bool, x=2) 194 195 def test_varargs4_kw(self): 196 msg = r"^index\(\) takes no keyword arguments$" 197 self.assertRaisesRegex(TypeError, msg, [].index, x=2) 198 199 def test_varargs5_kw(self): 200 msg = r"^hasattr\(\) takes no keyword arguments$" 201 self.assertRaisesRegex(TypeError, msg, hasattr, x=2) 202 203 def test_varargs6_kw(self): 204 msg = r"^getattr\(\) takes no keyword arguments$" 205 self.assertRaisesRegex(TypeError, msg, getattr, x=2) 206 207 def test_varargs7_kw(self): 208 msg = r"^next\(\) takes no keyword arguments$" 209 self.assertRaisesRegex(TypeError, msg, next, x=2) 210 211 def test_varargs8_kw(self): 212 msg = r"^pack\(\) takes no keyword arguments$" 213 self.assertRaisesRegex(TypeError, msg, struct.pack, x=2) 214 215 def test_varargs9_kw(self): 216 msg = r"^pack_into\(\) takes no keyword arguments$" 217 self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2) 218 219 def test_varargs10_kw(self): 220 msg = r"^index\(\) takes no keyword arguments$" 221 self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2) 222 223 def test_varargs11_kw(self): 224 msg = r"^pack\(\) takes no keyword arguments$" 225 self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2) 226 227 def test_varargs12_kw(self): 228 msg = r"^staticmethod\(\) takes no keyword arguments$" 229 self.assertRaisesRegex(TypeError, msg, staticmethod, func=id) 230 231 def test_varargs13_kw(self): 232 msg = r"^classmethod\(\) takes no keyword arguments$" 233 self.assertRaisesRegex(TypeError, msg, classmethod, func=id) 234 235 def test_varargs14_kw(self): 236 msg = r"^product\(\) takes at most 1 keyword argument \(2 given\)$" 237 self.assertRaisesRegex(TypeError, msg, 238 itertools.product, 0, repeat=1, foo=2) 239 240 def test_varargs15_kw(self): 241 msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$" 242 self.assertRaisesRegex(TypeError, msg, 243 ImportError, 0, name=1, path=2, foo=3) 244 245 def test_varargs16_kw(self): 246 msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$" 247 self.assertRaisesRegex(TypeError, msg, 248 min, 0, default=1, key=2, foo=3) 249 250 def test_varargs17_kw(self): 251 msg = r"^print\(\) takes at most 4 keyword arguments \(5 given\)$" 252 self.assertRaisesRegex(TypeError, msg, 253 print, 0, sep=1, end=2, file=3, flush=4, foo=5) 254 255 def test_oldargs0_1(self): 256 msg = r"keys\(\) takes no arguments \(1 given\)" 257 self.assertRaisesRegex(TypeError, msg, {}.keys, 0) 258 259 def test_oldargs0_2(self): 260 msg = r"keys\(\) takes no arguments \(2 given\)" 261 self.assertRaisesRegex(TypeError, msg, {}.keys, 0, 1) 262 263 def test_oldargs0_1_kw(self): 264 msg = r"keys\(\) takes no keyword arguments" 265 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2) 266 267 def test_oldargs0_2_kw(self): 268 msg = r"keys\(\) takes no keyword arguments" 269 self.assertRaisesRegex(TypeError, msg, {}.keys, x=2, y=2) 270 271 def test_oldargs1_0(self): 272 msg = r"count\(\) takes exactly one argument \(0 given\)" 273 self.assertRaisesRegex(TypeError, msg, [].count) 274 275 def test_oldargs1_2(self): 276 msg = r"count\(\) takes exactly one argument \(2 given\)" 277 self.assertRaisesRegex(TypeError, msg, [].count, 1, 2) 278 279 def test_oldargs1_0_kw(self): 280 msg = r"count\(\) takes no keyword arguments" 281 self.assertRaisesRegex(TypeError, msg, [].count, x=2) 282 283 def test_oldargs1_1_kw(self): 284 msg = r"count\(\) takes no keyword arguments" 285 self.assertRaisesRegex(TypeError, msg, [].count, {}, x=2) 286 287 def test_oldargs1_2_kw(self): 288 msg = r"count\(\) takes no keyword arguments" 289 self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2) 290 291 292def pyfunc(arg1, arg2): 293 return [arg1, arg2] 294 295 296def pyfunc_noarg(): 297 return "noarg" 298 299 300class PythonClass: 301 def method(self, arg1, arg2): 302 return [arg1, arg2] 303 304 def method_noarg(self): 305 return "noarg" 306 307 @classmethod 308 def class_method(cls): 309 return "classmethod" 310 311 @staticmethod 312 def static_method(): 313 return "staticmethod" 314 315 316PYTHON_INSTANCE = PythonClass() 317 318 319IGNORE_RESULT = object() 320 321 322@cpython_only 323class FastCallTests(unittest.TestCase): 324 # Test calls with positional arguments 325 CALLS_POSARGS = ( 326 # (func, args: tuple, result) 327 328 # Python function with 2 arguments 329 (pyfunc, (1, 2), [1, 2]), 330 331 # Python function without argument 332 (pyfunc_noarg, (), "noarg"), 333 334 # Python class methods 335 (PythonClass.class_method, (), "classmethod"), 336 (PythonClass.static_method, (), "staticmethod"), 337 338 # Python instance methods 339 (PYTHON_INSTANCE.method, (1, 2), [1, 2]), 340 (PYTHON_INSTANCE.method_noarg, (), "noarg"), 341 (PYTHON_INSTANCE.class_method, (), "classmethod"), 342 (PYTHON_INSTANCE.static_method, (), "staticmethod"), 343 344 # C function: METH_NOARGS 345 (globals, (), IGNORE_RESULT), 346 347 # C function: METH_O 348 (id, ("hello",), IGNORE_RESULT), 349 350 # C function: METH_VARARGS 351 (dir, (1,), IGNORE_RESULT), 352 353 # C function: METH_VARARGS | METH_KEYWORDS 354 (min, (5, 9), 5), 355 356 # C function: METH_FASTCALL 357 (divmod, (1000, 33), (30, 10)), 358 359 # C type static method: METH_FASTCALL | METH_CLASS 360 (int.from_bytes, (b'\x01\x00', 'little'), 1), 361 362 # bpo-30524: Test that calling a C type static method with no argument 363 # doesn't crash (ignore the result): METH_FASTCALL | METH_CLASS 364 (datetime.datetime.now, (), IGNORE_RESULT), 365 ) 366 367 # Test calls with positional and keyword arguments 368 CALLS_KWARGS = ( 369 # (func, args: tuple, kwargs: dict, result) 370 371 # Python function with 2 arguments 372 (pyfunc, (1,), {'arg2': 2}, [1, 2]), 373 (pyfunc, (), {'arg1': 1, 'arg2': 2}, [1, 2]), 374 375 # Python instance methods 376 (PYTHON_INSTANCE.method, (1,), {'arg2': 2}, [1, 2]), 377 (PYTHON_INSTANCE.method, (), {'arg1': 1, 'arg2': 2}, [1, 2]), 378 379 # C function: METH_VARARGS | METH_KEYWORDS 380 (max, ([],), {'default': 9}, 9), 381 382 # C type static method: METH_FASTCALL | METH_CLASS 383 (int.from_bytes, (b'\x01\x00',), {'byteorder': 'little'}, 1), 384 (int.from_bytes, (), {'bytes': b'\x01\x00', 'byteorder': 'little'}, 1), 385 ) 386 387 def check_result(self, result, expected): 388 if expected is IGNORE_RESULT: 389 return 390 self.assertEqual(result, expected) 391 392 def test_fastcall(self): 393 # Test _PyObject_FastCall() 394 395 for func, args, expected in self.CALLS_POSARGS: 396 with self.subTest(func=func, args=args): 397 result = _testcapi.pyobject_fastcall(func, args) 398 self.check_result(result, expected) 399 400 if not args: 401 # args=NULL, nargs=0 402 result = _testcapi.pyobject_fastcall(func, None) 403 self.check_result(result, expected) 404 405 def test_vectorcall_dict(self): 406 # Test _PyObject_FastCallDict() 407 408 for func, args, expected in self.CALLS_POSARGS: 409 with self.subTest(func=func, args=args): 410 # kwargs=NULL 411 result = _testcapi.pyobject_fastcalldict(func, args, None) 412 self.check_result(result, expected) 413 414 # kwargs={} 415 result = _testcapi.pyobject_fastcalldict(func, args, {}) 416 self.check_result(result, expected) 417 418 if not args: 419 # args=NULL, nargs=0, kwargs=NULL 420 result = _testcapi.pyobject_fastcalldict(func, None, None) 421 self.check_result(result, expected) 422 423 # args=NULL, nargs=0, kwargs={} 424 result = _testcapi.pyobject_fastcalldict(func, None, {}) 425 self.check_result(result, expected) 426 427 for func, args, kwargs, expected in self.CALLS_KWARGS: 428 with self.subTest(func=func, args=args, kwargs=kwargs): 429 result = _testcapi.pyobject_fastcalldict(func, args, kwargs) 430 self.check_result(result, expected) 431 432 def test_vectorcall(self): 433 # Test _PyObject_Vectorcall() 434 435 for func, args, expected in self.CALLS_POSARGS: 436 with self.subTest(func=func, args=args): 437 # kwnames=NULL 438 result = _testcapi.pyobject_vectorcall(func, args, None) 439 self.check_result(result, expected) 440 441 # kwnames=() 442 result = _testcapi.pyobject_vectorcall(func, args, ()) 443 self.check_result(result, expected) 444 445 if not args: 446 # kwnames=NULL 447 result = _testcapi.pyobject_vectorcall(func, None, None) 448 self.check_result(result, expected) 449 450 # kwnames=() 451 result = _testcapi.pyobject_vectorcall(func, None, ()) 452 self.check_result(result, expected) 453 454 for func, args, kwargs, expected in self.CALLS_KWARGS: 455 with self.subTest(func=func, args=args, kwargs=kwargs): 456 kwnames = tuple(kwargs.keys()) 457 args = args + tuple(kwargs.values()) 458 result = _testcapi.pyobject_vectorcall(func, args, kwnames) 459 self.check_result(result, expected) 460 461 def test_fastcall_clearing_dict(self): 462 # Test bpo-36907: the point of the test is just checking that this 463 # does not crash. 464 class IntWithDict: 465 __slots__ = ["kwargs"] 466 def __init__(self, **kwargs): 467 self.kwargs = kwargs 468 def __index__(self): 469 self.kwargs.clear() 470 gc.collect() 471 return 0 472 x = IntWithDict(dont_inherit=IntWithDict()) 473 # We test the argument handling of "compile" here, the compilation 474 # itself is not relevant. When we pass flags=x below, x.__index__() is 475 # called, which changes the keywords dict. 476 compile("pass", "", "exec", x, **x.kwargs) 477 478 479Py_TPFLAGS_HAVE_VECTORCALL = 1 << 11 480Py_TPFLAGS_METHOD_DESCRIPTOR = 1 << 17 481 482 483def testfunction(self): 484 """some doc""" 485 return self 486 487 488def testfunction_kw(self, *, kw): 489 """some doc""" 490 return self 491 492 493class TestPEP590(unittest.TestCase): 494 495 def test_method_descriptor_flag(self): 496 import functools 497 cached = functools.lru_cache(1)(testfunction) 498 499 self.assertFalse(type(repr).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 500 self.assertTrue(type(list.append).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 501 self.assertTrue(type(list.__add__).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 502 self.assertTrue(type(testfunction).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 503 self.assertTrue(type(cached).__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 504 505 self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 506 self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 507 self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 508 509 # Heap type should not inherit Py_TPFLAGS_METHOD_DESCRIPTOR 510 class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): 511 pass 512 self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) 513 514 def test_vectorcall_flag(self): 515 self.assertTrue(_testcapi.MethodDescriptorBase.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) 516 self.assertTrue(_testcapi.MethodDescriptorDerived.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) 517 self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) 518 self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) 519 520 # Heap type should not inherit Py_TPFLAGS_HAVE_VECTORCALL 521 class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): 522 pass 523 self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) 524 525 def test_vectorcall_override(self): 526 # Check that tp_call can correctly override vectorcall. 527 # MethodDescriptorNopGet implements tp_call but it inherits from 528 # MethodDescriptorBase, which implements vectorcall. Since 529 # MethodDescriptorNopGet returns the args tuple when called, we check 530 # additionally that no new tuple is created for this call. 531 args = tuple(range(5)) 532 f = _testcapi.MethodDescriptorNopGet() 533 self.assertIs(f(*args), args) 534 535 def test_vectorcall(self): 536 # Test a bunch of different ways to call objects: 537 # 1. vectorcall using PyVectorcall_Call() 538 # (only for objects that support vectorcall directly) 539 # 2. normal call 540 # 3. vectorcall using _PyObject_Vectorcall() 541 # 4. call as bound method 542 # 5. call using functools.partial 543 544 # A list of (function, args, kwargs, result) calls to test 545 calls = [(len, (range(42),), {}, 42), 546 (list.append, ([], 0), {}, None), 547 ([].append, (0,), {}, None), 548 (sum, ([36],), {"start":6}, 42), 549 (testfunction, (42,), {}, 42), 550 (testfunction_kw, (42,), {"kw":None}, 42), 551 (_testcapi.MethodDescriptorBase(), (0,), {}, True), 552 (_testcapi.MethodDescriptorDerived(), (0,), {}, True), 553 (_testcapi.MethodDescriptor2(), (0,), {}, False)] 554 555 from _testcapi import pyobject_vectorcall, pyvectorcall_call 556 from types import MethodType 557 from functools import partial 558 559 def vectorcall(func, args, kwargs): 560 args = *args, *kwargs.values() 561 kwnames = tuple(kwargs) 562 return pyobject_vectorcall(func, args, kwnames) 563 564 for (func, args, kwargs, expected) in calls: 565 with self.subTest(str(func)): 566 if not kwargs: 567 self.assertEqual(expected, pyvectorcall_call(func, args)) 568 self.assertEqual(expected, pyvectorcall_call(func, args, kwargs)) 569 570 # Add derived classes (which do not support vectorcall directly, 571 # but do support all other ways of calling). 572 573 class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): 574 pass 575 576 class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase): 577 def __call__(self, n): 578 return 'new' 579 580 class SuperBase: 581 def __call__(self, *args): 582 return super().__call__(*args) 583 584 class MethodDescriptorSuper(SuperBase, _testcapi.MethodDescriptorBase): 585 def __call__(self, *args): 586 return super().__call__(*args) 587 588 calls += [ 589 (dict.update, ({},), {"key":True}, None), 590 ({}.update, ({},), {"key":True}, None), 591 (MethodDescriptorHeap(), (0,), {}, True), 592 (MethodDescriptorOverridden(), (0,), {}, 'new'), 593 (MethodDescriptorSuper(), (0,), {}, True), 594 ] 595 596 for (func, args, kwargs, expected) in calls: 597 with self.subTest(str(func)): 598 args1 = args[1:] 599 meth = MethodType(func, args[0]) 600 wrapped = partial(func) 601 if not kwargs: 602 self.assertEqual(expected, func(*args)) 603 self.assertEqual(expected, pyobject_vectorcall(func, args, None)) 604 self.assertEqual(expected, meth(*args1)) 605 self.assertEqual(expected, wrapped(*args)) 606 self.assertEqual(expected, func(*args, **kwargs)) 607 self.assertEqual(expected, vectorcall(func, args, kwargs)) 608 self.assertEqual(expected, meth(*args1, **kwargs)) 609 self.assertEqual(expected, wrapped(*args, **kwargs)) 610 611 612if __name__ == "__main__": 613 unittest.main() 614