From bad7a35055dbe9e6297110eb8c72eb8edfefd42d Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 16 Oct 2023 17:26:11 +0300 Subject: gh-110907: AC: Disallow using `*` with vararg (#110908) --- Lib/test/test_clinic.py | 14 ++++++++++++++ Objects/clinic/typevarobject.c.h | 4 ++-- Objects/typevarobject.c | 3 +-- Tools/clinic/clinic.py | 9 +++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index 0499828..da957fc 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -359,6 +359,20 @@ class ClinicWholeFileTest(TestCase): """ 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): err = "Already defined module 'm'!" block = """ diff --git a/Objects/clinic/typevarobject.c.h b/Objects/clinic/typevarobject.c.h index 4762cd6..22090b1 100644 --- a/Objects/clinic/typevarobject.c.h +++ b/Objects/clinic/typevarobject.c.h @@ -8,7 +8,7 @@ preserve #endif 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" "--\n" "\n" @@ -590,4 +590,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=db0b327ebbb1488f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=027fb8cbef6e5015 input=a9049054013a1b77]*/ diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c index 8a20b23..51424ff 100644 --- a/Objects/typevarobject.c +++ b/Objects/typevarobject.c @@ -327,7 +327,6 @@ typevar.__new__ as typevar_new name: object(subclass_of="&PyUnicode_Type") *constraints: object - * bound: object = None covariant: bool = False contravariant: bool = False @@ -340,7 +339,7 @@ static PyObject * typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, PyObject *bound, int covariant, int contravariant, int infer_variance) -/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/ +/*[clinic end generated code: output=1d200450ee99226d input=41ae33a916bfe76f]*/ { if (covariant && contravariant) { PyErr_SetString(PyExc_ValueError, diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 1bcc855..a549865 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -5944,6 +5944,7 @@ class DSLParser: if version is None: if self.keyword_only: fail(f"Function {function.name!r} uses '*' more than once.") + self.check_previous_star() self.check_remaining_star() self.keyword_only = True else: @@ -6353,6 +6354,14 @@ class DSLParser: fail(f"Function {self.function.name!r} specifies {symbol!r} " 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: """ Called when processing the block is done. -- cgit v0.12