Skip to content

gh-122688: Fix support of var-positional parameter in Argument Clinic #122689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Lib/test/clinic.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -4134,8 +4134,8 @@ test_vararg_and_posonly


a: object
*args: object
/
*args: object

[clinic start generated code]*/

Expand Down Expand Up @@ -4177,7 +4177,7 @@ test_vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t narg

static PyObject *
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args)
/*[clinic end generated code: output=79b75dc07decc8d6 input=08dc2bf7afbf1613]*/
/*[clinic end generated code: output=79b75dc07decc8d6 input=9cfa748bbff09877]*/

/*[clinic input]
test_vararg
Expand Down Expand Up @@ -4920,7 +4920,7 @@ Test_an_metho_arg_named_arg_impl(TestObj *self, int arg)
/*[clinic input]
Test.__init__
*args: object
/

Varargs init method. For example, nargs is translated to PyTuple_GET_SIZE.
[clinic start generated code]*/

Expand Down Expand Up @@ -4958,14 +4958,14 @@ Test___init__(PyObject *self, PyObject *args, PyObject *kwargs)

static int
Test___init___impl(TestObj *self, PyObject *args)
/*[clinic end generated code: output=0ed1009fe0dcf98d input=96c3ddc0cd38fc0c]*/
/*[clinic end generated code: output=0ed1009fe0dcf98d input=2a8bd0033c9ac772]*/


/*[clinic input]
@classmethod
Test.__new__
*args: object
/

Varargs new method. For example, nargs is translated to PyTuple_GET_SIZE.
[clinic start generated code]*/

Expand Down Expand Up @@ -5002,7 +5002,7 @@ Test(PyTypeObject *type, PyObject *args, PyObject *kwargs)

static PyObject *
Test_impl(PyTypeObject *type, PyObject *args)
/*[clinic end generated code: output=8b219f6633e2a2e9 input=26a672e2e9750120]*/
/*[clinic end generated code: output=8b219f6633e2a2e9 input=70ad829df3dd9b84]*/


/*[clinic input]
Expand Down
96 changes: 85 additions & 11 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def __init__(self):
"""
self.expect_failure(block, err, lineno=8)

def test_multiple_star_in_args(self):
def test_star_after_vararg(self):
err = "'my_test_func' uses '*' more than once."
block = """
/*[clinic input]
Expand All @@ -336,6 +336,20 @@ def test_multiple_star_in_args(self):
"""
self.expect_failure(block, err, lineno=6)

def test_vararg_after_star(self):
err = "'my_test_func' uses '*' more than once."
block = """
/*[clinic input]
my_test_func

pos_arg: object
*
*args: object
kw_arg: object
[clinic start generated code]*/
"""
self.expect_failure(block, err, lineno=6)

def test_module_already_got_one(self):
err = "Already defined module 'm'!"
block = """
Expand Down Expand Up @@ -1787,13 +1801,43 @@ def test_parameters_required_after_depr_star2(self):
)
self.expect_failure(block, err, lineno=4)

def test_parameters_required_after_depr_star3(self):
block = """
module foo
foo.bar
a: int
* [from 3.14]
*args: object
b: int
Docstring.
"""
err = (
"Function 'bar' specifies '* [from ...]' without "
"following parameters."
)
self.expect_failure(block, err, lineno=4)

def test_depr_star_must_come_before_star(self):
block = """
module foo
foo.bar
this: int
a: int
*
* [from 3.14]
b: int
Docstring.
"""
err = "Function 'bar': '* [from ...]' must precede '*'"
self.expect_failure(block, err, lineno=4)

def test_depr_star_must_come_before_vararg(self):
block = """
module foo
foo.bar
a: int
*args: object
* [from 3.14]
b: int
Docstring.
"""
err = "Function 'bar': '* [from ...]' must precede '*'"
Expand Down Expand Up @@ -1908,7 +1952,7 @@ def test_double_slash(self):
err = "Function 'bar' uses '/' more than once."
self.expect_failure(block, err)

def test_mix_star_and_slash(self):
def test_slash_after_star(self):
block = """
module foo
foo.bar
Expand All @@ -1921,6 +1965,19 @@ def test_mix_star_and_slash(self):
err = "Function 'bar': '/' must precede '*'"
self.expect_failure(block, err)

def test_slash_after_vararg(self):
block = """
module foo
foo.bar
x: int
y: int
*args: object
z: int
/
"""
err = "Function 'bar': '/' must precede '*'"
self.expect_failure(block, err)

def test_depr_star_must_come_after_slash(self):
block = """
module foo
Expand Down Expand Up @@ -1960,6 +2017,19 @@ def test_star_must_come_after_depr_slash(self):
err = "Function 'bar': '/ [from ...]' must precede '*'"
self.expect_failure(block, err, lineno=4)

def test_vararg_must_come_after_depr_slash(self):
block = """
module foo
foo.bar
a: int
*args: object
/ [from 3.14]
b: int
Docstring.
"""
err = "Function 'bar': '/ [from ...]' must precede '*'"
self.expect_failure(block, err, lineno=4)

def test_depr_slash_must_come_after_slash(self):
block = """
module foo
Expand Down Expand Up @@ -1987,7 +2057,7 @@ def test_parameters_not_permitted_after_slash_for_now(self):
self.expect_failure(block, err)

def test_parameters_no_more_than_one_vararg(self):
err = "Too many var args"
err = "Function 'bar' uses '*' more than once."
block = """
module foo
foo.bar
Expand Down Expand Up @@ -3319,13 +3389,6 @@ def test_posonly_vararg(self):
with self.assertRaises(TypeError):
ac_tester.posonly_vararg(1, 2, 3, b=4)

def test_vararg_and_posonly(self):
with self.assertRaises(TypeError):
ac_tester.vararg_and_posonly()
with self.assertRaises(TypeError):
ac_tester.vararg_and_posonly(1, b=2)
self.assertEqual(ac_tester.vararg_and_posonly(1, 2, 3, 4), (1, (2, 3, 4)))

def test_vararg(self):
with self.assertRaises(TypeError):
ac_tester.vararg()
Expand Down Expand Up @@ -3363,6 +3426,17 @@ def test_vararg_with_only_defaults(self):
self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4), ((1, 2, 3, 4), None))
self.assertEqual(ac_tester.vararg_with_only_defaults(1, 2, 3, 4, b=5), ((1, 2, 3, 4), 5))

def test_vararg_kwonly_req_opt(self):
fn = ac_tester.vararg_kwonly_req_opt
self.assertRaises(TypeError, fn)
self.assertEqual(fn(a=1), ((), 1, None, None))
self.assertEqual(fn(a=1, b=2), ((), 1, 2, None))
self.assertEqual(fn(a=1, b=2, c=3), ((), 1, 2, 3))
self.assertRaises(TypeError, fn, 1)
self.assertEqual(fn(1, a=2), ((1,), 2, None, None))
self.assertEqual(fn(1, a=2, b=3), ((1,), 2, 3, None))
self.assertEqual(fn(1, a=2, b=3, c=4), ((1,), 2, 3, 4))

def test_gh_32092_oob(self):
ac_tester.gh_32092_oob(1, 2, 3, 4, kw1=5, kw2=6)

Expand Down
41 changes: 21 additions & 20 deletions Modules/_testclinic.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,23 +981,6 @@ posonly_vararg_impl(PyObject *module, PyObject *a, PyObject *b,
}


/*[clinic input]
vararg_and_posonly

a: object
*args: object
/

[clinic start generated code]*/

static PyObject *
vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args)
/*[clinic end generated code: output=42792f799465a14d input=defe017b19ba52e8]*/
{
return pack_arguments_newref(2, a, args);
}


/*[clinic input]
vararg

Expand Down Expand Up @@ -1068,6 +1051,25 @@ vararg_with_only_defaults_impl(PyObject *module, PyObject *args, PyObject *b)
}


/*[clinic input]
vararg_kwonly_req_opt

*args: object
a: object
b: object = None
c: object = None

[clinic start generated code]*/

static PyObject *
vararg_kwonly_req_opt_impl(PyObject *module, PyObject *args, PyObject *a,
PyObject *b, PyObject *c)
/*[clinic end generated code: output=54694a99c3da370a input=b0d8bf09e540d400]*/
{
return pack_arguments_newref(4, args, a, b, c);
}



/*[clinic input]
gh_32092_oob
Expand Down Expand Up @@ -1115,15 +1117,14 @@ gh_32092_kw_pass_impl(PyObject *module, PyObject *pos, PyObject *args,
gh_99233_refcount

*args: object
/

Proof-of-concept of GH-99233 refcount error bug.

[clinic start generated code]*/

static PyObject *
gh_99233_refcount_impl(PyObject *module, PyObject *args)
/*[clinic end generated code: output=585855abfbca9a7f input=85f5fb47ac91a626]*/
/*[clinic end generated code: output=585855abfbca9a7f input=eecfdc2092d90dc3]*/
{
Py_RETURN_NONE;
}
Expand Down Expand Up @@ -1923,11 +1924,11 @@ static PyMethodDef tester_methods[] = {
POSONLY_OPT_KEYWORDS_OPT_KWONLY_OPT_METHODDEF
KEYWORD_ONLY_PARAMETER_METHODDEF
POSONLY_VARARG_METHODDEF
VARARG_AND_POSONLY_METHODDEF
VARARG_METHODDEF
VARARG_WITH_DEFAULT_METHODDEF
VARARG_WITH_DEFAULT2_METHODDEF
VARARG_WITH_ONLY_DEFAULTS_METHODDEF
VARARG_KWONLY_REQ_OPT_METHODDEF
GH_32092_OOB_METHODDEF
GH_32092_KW_PASS_METHODDEF
GH_99233_REFCOUNT_METHODDEF
Expand Down
Loading
Loading