Issue #26282: PyArg_ParseTupleAndKeywords() and Argument Clinic now support

positional-only and keyword parameters in the same function.
This commit is contained in:
Serhiy Storchaka 2016-06-09 16:30:29 +03:00
parent 339880809a
commit f41b82fb19
9 changed files with 210 additions and 72 deletions

View file

@ -527,6 +527,31 @@ class SkipitemTest(unittest.TestCase):
self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords,
(), {}, b'', [42])
def test_positional_only(self):
parse = _testcapi.parse_tuple_and_keywords
parse((1, 2, 3), {}, b'OOO', ['', '', 'a'])
parse((1, 2), {'a': 3}, b'OOO', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
'Function takes at least 2 positional arguments \(1 given\)'):
parse((1,), {'a': 3}, b'OOO', ['', '', 'a'])
parse((1,), {}, b'O|OO', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
'Function takes at least 1 positional arguments \(0 given\)'):
parse((), {}, b'O|OO', ['', '', 'a'])
parse((1, 2), {'a': 3}, b'OO$O', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
'Function takes exactly 2 positional arguments \(1 given\)'):
parse((1,), {'a': 3}, b'OO$O', ['', '', 'a'])
parse((1,), {}, b'O|O$O', ['', '', 'a'])
with self.assertRaisesRegex(TypeError,
'Function takes at least 1 positional arguments \(0 given\)'):
parse((), {}, b'O|O$O', ['', '', 'a'])
with self.assertRaisesRegex(SystemError, 'Empty parameter name after \$'):
parse((1,), {}, b'O|$OO', ['', '', 'a'])
with self.assertRaisesRegex(SystemError, 'Empty keyword'):
parse((1,), {}, b'O|OO', ['', 'a', ''])
@unittest.skipUnless(threading, 'Threading required for this test.')
class TestThreadState(unittest.TestCase):

View file

@ -658,6 +658,39 @@ class KeywordOnly_TestCase(unittest.TestCase):
getargs_keyword_only(1, 2, **{'\uDC80': 10})
class PositionalOnlyAndKeywords_TestCase(unittest.TestCase):
from _testcapi import getargs_positional_only_and_keywords as getargs
def test_positional_args(self):
# using all possible positional args
self.assertEqual(self.getargs(1, 2, 3), (1, 2, 3))
def test_mixed_args(self):
# positional and keyword args
self.assertEqual(self.getargs(1, 2, keyword=3), (1, 2, 3))
def test_optional_args(self):
# missing optional args
self.assertEqual(self.getargs(1, 2), (1, 2, -1))
self.assertEqual(self.getargs(1, keyword=3), (1, -1, 3))
def test_required_args(self):
self.assertEqual(self.getargs(1), (1, -1, -1))
# required positional arg missing
with self.assertRaisesRegex(TypeError,
"Function takes at least 1 positional arguments \(0 given\)"):
self.getargs()
with self.assertRaisesRegex(TypeError,
"Function takes at least 1 positional arguments \(0 given\)"):
self.getargs(keyword=3)
def test_empty_keyword(self):
with self.assertRaisesRegex(TypeError,
"'' is an invalid keyword argument for this function"):
self.getargs(1, 2, **{'': 666})
class Bytes_TestCase(unittest.TestCase):
def test_c(self):
from _testcapi import getargs_c