]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-110907: AC: Disallow using `*` with vararg (#110908)
authorNikita Sobolev <mail@sobolevn.me>
Mon, 16 Oct 2023 14:26:11 +0000 (17:26 +0300)
committerGitHub <noreply@github.com>
Mon, 16 Oct 2023 14:26:11 +0000 (15:26 +0100)
Lib/test/test_clinic.py
Objects/clinic/typevarobject.c.h
Objects/typevarobject.c
Tools/clinic/clinic.py

index 0499828e4dedbc3f3f4e2cb90456b00babcbac34..da957fcebaa2961d61e5ed3c742e4f5c89160440 100644 (file)
@@ -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 = """
index 4762cd63545b60e3a55dd3306c40f1caccff2cf0..22090b15481431440fa8037b2f817a517804d88d 100644 (file)
@@ -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]*/
index 8a20b23c6866d7047c99cb364dbc5a9118661fda..51424ffb24e2bf7ecb81882b4e6e45820ead582c 100644 (file)
@@ -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,
index 1bcc85537bf2da25d91bac14ea3098c4ec03857d..a54986506066f4129088814c11cc3139fd339816 100755 (executable)
@@ -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.