mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
gh-95065, gh-107704: Argument Clinic: support multiple '/ [from ...]' and '* [from ...]' markers (GH-108132)
This commit is contained in:
parent
13104f3b74
commit
60942cccb1
8 changed files with 565 additions and 104 deletions
|
@ -1751,7 +1751,7 @@ class ClinicParserTest(TestCase):
|
|||
* [from 3.14]
|
||||
Docstring.
|
||||
"""
|
||||
err = "Function 'bar': '* [from ...]' must come before '*'"
|
||||
err = "Function 'bar': '* [from ...]' must precede '*'"
|
||||
self.expect_failure(block, err, lineno=4)
|
||||
|
||||
def test_depr_star_duplicate(self):
|
||||
|
@ -1765,7 +1765,7 @@ class ClinicParserTest(TestCase):
|
|||
c: int
|
||||
Docstring.
|
||||
"""
|
||||
err = "Function 'bar' uses '* [from ...]' more than once."
|
||||
err = "Function 'bar' uses '* [from 3.14]' more than once."
|
||||
self.expect_failure(block, err, lineno=5)
|
||||
|
||||
def test_depr_star_duplicate2(self):
|
||||
|
@ -1779,7 +1779,7 @@ class ClinicParserTest(TestCase):
|
|||
c: int
|
||||
Docstring.
|
||||
"""
|
||||
err = "Function 'bar' uses '* [from ...]' more than once."
|
||||
err = "Function 'bar': '* [from 3.15]' must precede '* [from 3.14]'"
|
||||
self.expect_failure(block, err, lineno=5)
|
||||
|
||||
def test_depr_slash_duplicate(self):
|
||||
|
@ -1793,7 +1793,7 @@ class ClinicParserTest(TestCase):
|
|||
c: int
|
||||
Docstring.
|
||||
"""
|
||||
err = "Function 'bar' uses '/ [from ...]' more than once."
|
||||
err = "Function 'bar' uses '/ [from 3.14]' more than once."
|
||||
self.expect_failure(block, err, lineno=5)
|
||||
|
||||
def test_depr_slash_duplicate2(self):
|
||||
|
@ -1801,13 +1801,13 @@ class ClinicParserTest(TestCase):
|
|||
module foo
|
||||
foo.bar
|
||||
a: int
|
||||
/ [from 3.14]
|
||||
b: int
|
||||
/ [from 3.15]
|
||||
b: int
|
||||
/ [from 3.14]
|
||||
c: int
|
||||
Docstring.
|
||||
"""
|
||||
err = "Function 'bar' uses '/ [from ...]' more than once."
|
||||
err = "Function 'bar': '/ [from 3.14]' must precede '/ [from 3.15]'"
|
||||
self.expect_failure(block, err, lineno=5)
|
||||
|
||||
def test_single_slash(self):
|
||||
|
@ -2724,7 +2724,15 @@ class ClinicFunctionalTest(unittest.TestCase):
|
|||
locals().update((name, getattr(ac_tester, name))
|
||||
for name in dir(ac_tester) if name.startswith('test_'))
|
||||
|
||||
def check_depr_star(self, pnames, fn, *args, name=None, **kwds):
|
||||
def check_depr(self, regex, fn, /, *args, **kwds):
|
||||
with self.assertWarnsRegex(DeprecationWarning, regex) as cm:
|
||||
# Record the line number, so we're sure we've got the correct stack
|
||||
# level on the deprecation warning.
|
||||
_, lineno = fn(*args, **kwds), sys._getframe().f_lineno
|
||||
self.assertEqual(cm.filename, __file__)
|
||||
self.assertEqual(cm.lineno, lineno)
|
||||
|
||||
def check_depr_star(self, pnames, fn, /, *args, name=None, **kwds):
|
||||
if name is None:
|
||||
name = fn.__qualname__
|
||||
if isinstance(fn, type):
|
||||
|
@ -2734,12 +2742,7 @@ class ClinicFunctionalTest(unittest.TestCase):
|
|||
fr"{re.escape(name)}\(\) is deprecated. Parameters? {pnames} will "
|
||||
fr"become( a)? keyword-only parameters? in Python 3\.14"
|
||||
)
|
||||
with self.assertWarnsRegex(DeprecationWarning, regex) as cm:
|
||||
# Record the line number, so we're sure we've got the correct stack
|
||||
# level on the deprecation warning.
|
||||
_, lineno = fn(*args, **kwds), sys._getframe().f_lineno
|
||||
self.assertEqual(cm.filename, __file__)
|
||||
self.assertEqual(cm.lineno, lineno)
|
||||
self.check_depr(regex, fn, *args, **kwds)
|
||||
|
||||
def check_depr_kwd(self, pnames, fn, *args, name=None, **kwds):
|
||||
if name is None:
|
||||
|
@ -2749,15 +2752,10 @@ class ClinicFunctionalTest(unittest.TestCase):
|
|||
pl = 's' if ' ' in pnames else ''
|
||||
regex = (
|
||||
fr"Passing keyword argument{pl} {pnames} to "
|
||||
fr"{re.escape(name)}\(\) is deprecated. Corresponding parameter{pl} "
|
||||
fr"{re.escape(name)}\(\) is deprecated. Parameter{pl} {pnames} "
|
||||
fr"will become positional-only in Python 3\.14."
|
||||
)
|
||||
with self.assertWarnsRegex(DeprecationWarning, regex) as cm:
|
||||
# Record the line number, so we're sure we've got the correct stack
|
||||
# level on the deprecation warning.
|
||||
_, lineno = fn(*args, **kwds), sys._getframe().f_lineno
|
||||
self.assertEqual(cm.filename, __file__)
|
||||
self.assertEqual(cm.lineno, lineno)
|
||||
self.check_depr(regex, fn, *args, **kwds)
|
||||
|
||||
def test_objects_converter(self):
|
||||
with self.assertRaises(TypeError):
|
||||
|
@ -3368,6 +3366,24 @@ class ClinicFunctionalTest(unittest.TestCase):
|
|||
check("a", "b", c="c")
|
||||
self.assertRaises(TypeError, fn, "a", "b", "c", "d")
|
||||
|
||||
def test_depr_star_multi(self):
|
||||
fn = ac_tester.depr_star_multi
|
||||
self.assertRaises(TypeError, fn, "a")
|
||||
fn("a", b="b", c="c", d="d", e="e", f="f", g="g", h="h")
|
||||
errmsg = (
|
||||
"Passing more than 1 positional argument to depr_star_multi() is deprecated. "
|
||||
"Parameter 'b' will become a keyword-only parameter in Python 3.16. "
|
||||
"Parameters 'c' and 'd' will become keyword-only parameters in Python 3.15. "
|
||||
"Parameters 'e', 'f' and 'g' will become keyword-only parameters in Python 3.14.")
|
||||
check = partial(self.check_depr, re.escape(errmsg), fn)
|
||||
check("a", "b", c="c", d="d", e="e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", d="d", e="e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", "d", e="e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", "d", "e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", "d", "e", "f", g="g", h="h")
|
||||
check("a", "b", "c", "d", "e", "f", "g", h="h")
|
||||
self.assertRaises(TypeError, fn, "a", "b", "c", "d", "e", "f", "g", "h")
|
||||
|
||||
def test_depr_kwd_required_1(self):
|
||||
fn = ac_tester.depr_kwd_required_1
|
||||
fn("a", "b")
|
||||
|
@ -3452,6 +3468,44 @@ class ClinicFunctionalTest(unittest.TestCase):
|
|||
self.assertRaises(TypeError, fn, "a", c="c")
|
||||
self.assertRaises(TypeError, fn, a="a", b="b", c="c")
|
||||
|
||||
def test_depr_kwd_multi(self):
|
||||
fn = ac_tester.depr_kwd_multi
|
||||
fn("a", "b", "c", "d", "e", "f", "g", h="h")
|
||||
errmsg = (
|
||||
"Passing keyword arguments 'b', 'c', 'd', 'e', 'f' and 'g' to depr_kwd_multi() is deprecated. "
|
||||
"Parameter 'b' will become positional-only in Python 3.14. "
|
||||
"Parameters 'c' and 'd' will become positional-only in Python 3.15. "
|
||||
"Parameters 'e', 'f' and 'g' will become positional-only in Python 3.16.")
|
||||
check = partial(self.check_depr, re.escape(errmsg), fn)
|
||||
check("a", "b", "c", "d", "e", "f", g="g", h="h")
|
||||
check("a", "b", "c", "d", "e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", "d", e="e", f="f", g="g", h="h")
|
||||
check("a", "b", "c", d="d", e="e", f="f", g="g", h="h")
|
||||
check("a", "b", c="c", d="d", e="e", f="f", g="g", h="h")
|
||||
check("a", b="b", c="c", d="d", e="e", f="f", g="g", h="h")
|
||||
self.assertRaises(TypeError, fn, a="a", b="b", c="c", d="d", e="e", f="f", g="g", h="h")
|
||||
|
||||
def test_depr_multi(self):
|
||||
fn = ac_tester.depr_multi
|
||||
self.assertRaises(TypeError, fn, "a", "b", "c", "d", "e", "f", "g")
|
||||
errmsg = (
|
||||
"Passing more than 4 positional arguments to depr_multi() is deprecated. "
|
||||
"Parameter 'e' will become a keyword-only parameter in Python 3.15. "
|
||||
"Parameter 'f' will become a keyword-only parameter in Python 3.14.")
|
||||
check = partial(self.check_depr, re.escape(errmsg), fn)
|
||||
check("a", "b", "c", "d", "e", "f", g="g")
|
||||
check("a", "b", "c", "d", "e", f="f", g="g")
|
||||
fn("a", "b", "c", "d", e="e", f="f", g="g")
|
||||
fn("a", "b", "c", d="d", e="e", f="f", g="g")
|
||||
errmsg = (
|
||||
"Passing keyword arguments 'b' and 'c' to depr_multi() is deprecated. "
|
||||
"Parameter 'b' will become positional-only in Python 3.14. "
|
||||
"Parameter 'c' will become positional-only in Python 3.15.")
|
||||
check = partial(self.check_depr, re.escape(errmsg), fn)
|
||||
check("a", "b", c="c", d="d", e="e", f="f", g="g")
|
||||
check("a", b="b", c="c", d="d", e="e", f="f", g="g")
|
||||
self.assertRaises(TypeError, fn, a="a", b="b", c="c", d="d", e="e", f="f", g="g")
|
||||
|
||||
|
||||
class PermutationTests(unittest.TestCase):
|
||||
"""Test permutation support functions."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue