diff options
author | Jeroen Demeyer <J.Demeyer@UGent.be> | 2019-05-29 18:31:52 (GMT) |
---|---|---|
committer | Petr Viktorin <encukou@gmail.com> | 2019-05-29 18:31:52 (GMT) |
commit | aacc77fbd77640a8f03638216fa09372cc21673d (patch) | |
tree | fd64be1c4c1167a8bf708d1fd22c733cf3a9a30f /Lib/test/test_capi.py | |
parent | d30da5dd9a8a965cf24a22bbaff8a5b1341c2944 (diff) | |
download | cpython-aacc77fbd77640a8f03638216fa09372cc21673d.zip cpython-aacc77fbd77640a8f03638216fa09372cc21673d.tar.gz cpython-aacc77fbd77640a8f03638216fa09372cc21673d.tar.bz2 |
bpo-36974: implement PEP 590 (GH-13185)
Co-authored-by: Jeroen Demeyer <J.Demeyer@UGent.be>
Co-authored-by: Mark Shannon <mark@hotpy.org>
Diffstat (limited to 'Lib/test/test_capi.py')
-rw-r--r-- | Lib/test/test_capi.py | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index f3d41a2..0813abb 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -34,6 +34,11 @@ def testfunction(self): """some doc""" return self +def testfunction_kw(self, *, kw): + """some doc""" + return self + + class InstanceMethod: id = _testcapi.instancemethod(id) testfunction = _testcapi.instancemethod(testfunction) @@ -479,6 +484,48 @@ class TestPEP590(unittest.TestCase): pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_METHOD_DESCRIPTOR) + def test_vectorcall(self): + # Test a bunch of different ways to call objects: + # 1. normal call + # 2. vectorcall using _PyObject_Vectorcall() + # 3. vectorcall using PyVectorcall_Call() + # 4. call as bound method + # 5. call using functools.partial + + # A list of (function, args, kwargs, result) calls to test + 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)] + + 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)): + 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, pyvectorcall_call(func, args)) + 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, pyvectorcall_call(func, args, kwargs)) + self.assertEqual(expected, meth(*args1, **kwargs)) + self.assertEqual(expected, wrapped(*args, **kwargs)) + class SubinterpreterTest(unittest.TestCase): |