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