gh-110907: AC: Disallow using `*` with vararg (#110908)

This commit is contained in:
Nikita Sobolev 2023-10-16 17:26:11 +03:00 committed by GitHub
parent 14d2d1576d
commit bad7a35055
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 4 deletions

View File

@ -359,6 +359,20 @@ class ClinicWholeFileTest(TestCase):
""" """
self.expect_failure(block, err, lineno=8) self.expect_failure(block, err, lineno=8)
def test_multiple_star_in_args(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): def test_module_already_got_one(self):
err = "Already defined module 'm'!" err = "Already defined module 'm'!"
block = """ block = """

View File

@ -8,7 +8,7 @@ preserve
#endif #endif
PyDoc_STRVAR(typevar_new__doc__, PyDoc_STRVAR(typevar_new__doc__,
"typevar(name, *constraints, *, bound=None, covariant=False,\n" "typevar(name, *constraints, bound=None, covariant=False,\n"
" contravariant=False, infer_variance=False)\n" " contravariant=False, infer_variance=False)\n"
"--\n" "--\n"
"\n" "\n"
@ -590,4 +590,4 @@ skip_optional_kwonly:
exit: exit:
return return_value; return return_value;
} }
/*[clinic end generated code: output=db0b327ebbb1488f input=a9049054013a1b77]*/ /*[clinic end generated code: output=027fb8cbef6e5015 input=a9049054013a1b77]*/

View File

@ -327,7 +327,6 @@ typevar.__new__ as typevar_new
name: object(subclass_of="&PyUnicode_Type") name: object(subclass_of="&PyUnicode_Type")
*constraints: object *constraints: object
*
bound: object = None bound: object = None
covariant: bool = False covariant: bool = False
contravariant: bool = False contravariant: bool = False
@ -340,7 +339,7 @@ static PyObject *
typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints,
PyObject *bound, int covariant, int contravariant, PyObject *bound, int covariant, int contravariant,
int infer_variance) int infer_variance)
/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/ /*[clinic end generated code: output=1d200450ee99226d input=41ae33a916bfe76f]*/
{ {
if (covariant && contravariant) { if (covariant && contravariant) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,

View File

@ -5944,6 +5944,7 @@ class DSLParser:
if version is None: if version is None:
if self.keyword_only: if self.keyword_only:
fail(f"Function {function.name!r} uses '*' more than once.") fail(f"Function {function.name!r} uses '*' more than once.")
self.check_previous_star()
self.check_remaining_star() self.check_remaining_star()
self.keyword_only = True self.keyword_only = True
else: else:
@ -6353,6 +6354,14 @@ class DSLParser:
fail(f"Function {self.function.name!r} specifies {symbol!r} " fail(f"Function {self.function.name!r} specifies {symbol!r} "
f"without following parameters.", line_number=lineno) f"without following parameters.", line_number=lineno)
def check_previous_star(self, lineno: int | None = None) -> None:
assert isinstance(self.function, Function)
for p in self.function.parameters.values():
if p.kind == inspect.Parameter.VAR_POSITIONAL:
fail(f"Function {self.function.name!r} uses '*' more than once.")
def do_post_block_processing_cleanup(self, lineno: int) -> None: def do_post_block_processing_cleanup(self, lineno: int) -> None:
""" """
Called when processing the block is done. Called when processing the block is done.