Skip to content

Commit a417c5b

Browse files
Reject a var-positional or var-keyword parameter in an optional group
They were reported as an error on the following line, which was confusing: the closing ']' was blamed for following a var-keyword parameter.
1 parent 31d53ce commit a417c5b

2 files changed

Lines changed: 19 additions & 18 deletions

File tree

‎Lib/test/test_clinic.py‎

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,9 +2130,8 @@ def test_disallowed_grouping__parameter_after_group(self):
21302130
# Only positional-only parameters can follow an optional group.
21312131
group_err = ("You cannot use optional groups ('[' and ']') unless all "
21322132
"parameters are positional-only ('/')")
2133-
kwds_err = ("Function 'bar' uses a var-keyword parameter and other "
2134-
"non-positional parameters, which Argument Clinic does "
2135-
"not currently support: '**kwds: dict'")
2133+
kwds_err = ("cannot use a var-keyword parameter with pos-or-keyword "
2134+
"or keyword-only parameters")
21362135
dataset = (("""
21372136
module foo
21382137
foo.bar
@@ -2717,7 +2716,7 @@ def test_group_with_var_keyword(self):
27172716
**kwds: dict
27182717
]
27192718
"""
2720-
err = "parameters cannot follow var-keyword parameter: ']'"
2719+
err = "A var-keyword parameter cannot be in an optional group."
27212720
self.expect_failure(block, err)
27222721

27232722
def test_group_with_var_positional(self):
@@ -2727,8 +2726,7 @@ def test_group_with_var_positional(self):
27272726
*args: tuple
27282727
]
27292728
"""
2730-
err = ("You cannot use optional groups ('[' and ']') unless all "
2731-
"parameters are positional-only ('/')")
2729+
err = "A var-positional parameter cannot be in an optional group."
27322730
self.expect_failure(block, err)
27332731

27342732
def test_depr_star_must_come_after_slash(self):
@@ -3630,9 +3628,8 @@ def test_var_keyword_with_pos_or_kw(self):
36303628
x: int
36313629
**kwds: dict
36323630
"""
3633-
err = ("Function 'bar' uses a var-keyword parameter and other "
3634-
"non-positional parameters, which Argument Clinic does "
3635-
"not currently support: '**kwds: dict'")
3631+
err = ("Function 'bar' cannot use a var-keyword parameter with "
3632+
"pos-or-keyword or keyword-only parameters.")
36363633
self.expect_failure(block, err)
36373634

36383635
def test_var_keyword_with_kw_only(self):
@@ -3645,9 +3642,8 @@ def test_var_keyword_with_kw_only(self):
36453642
y: int
36463643
**kwds: dict
36473644
"""
3648-
err = ("Function 'bar' uses a var-keyword parameter and other "
3649-
"non-positional parameters, which Argument Clinic does "
3650-
"not currently support: '**kwds: dict'")
3645+
err = ("Function 'bar' cannot use a var-keyword parameter with "
3646+
"pos-or-keyword or keyword-only parameters.")
36513647
self.expect_failure(block, err)
36523648

36533649
def test_var_keyword_with_pos_or_kw_and_kw_only(self):
@@ -3661,9 +3657,8 @@ def test_var_keyword_with_pos_or_kw_and_kw_only(self):
36613657
z: int
36623658
**kwds: dict
36633659
"""
3664-
err = ("Function 'bar' uses a var-keyword parameter and other "
3665-
"non-positional parameters, which Argument Clinic does "
3666-
"not currently support: '**kwds: dict'")
3660+
err = ("Function 'bar' cannot use a var-keyword parameter with "
3661+
"pos-or-keyword or keyword-only parameters.")
36673662
self.expect_failure(block, err)
36683663

36693664
def test_allow_negative_accepted_by_py_ssize_t_converter_only(self):

‎Tools/clinic/libclinic/dsl_parser.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,9 +1020,9 @@ def parse_parameter(self, line: str) -> None:
10201020
for p in self.function.parameters.values()
10211021
)
10221022
if has_non_positional_param:
1023-
fail(f'Function {self.function.name!r} uses a var-keyword parameter '
1024-
f'and other non-positional parameters, which Argument Clinic '
1025-
f'does not currently support: {line!r}')
1023+
fail(f'Function {self.function.name!r} cannot use a var-keyword '
1024+
f'parameter with pos-or-keyword or keyword-only '
1025+
f'parameters.')
10261026
is_var_keyword = True
10271027
parameter = function_args.kwarg
10281028
else:
@@ -1161,6 +1161,9 @@ def bad_node(self, node: ast.AST) -> None:
11611161

11621162
kind: inspect._ParameterKind
11631163
if is_vararg:
1164+
if self.group_stack:
1165+
fail("A var-positional parameter cannot be in an optional "
1166+
"group.")
11641167
if any(p.group for p in self.function.parameters.values()):
11651168
# With "foo([a, b], *args)" the number of arguments does not
11661169
# tell whether the group is passed or all arguments belong
@@ -1169,6 +1172,9 @@ def bad_node(self, node: ast.AST) -> None:
11691172
f"groups with a var-positional parameter.")
11701173
kind = inspect.Parameter.VAR_POSITIONAL
11711174
elif is_var_keyword:
1175+
if self.group_stack:
1176+
fail("A var-keyword parameter cannot be in an optional "
1177+
"group.")
11721178
kind = inspect.Parameter.VAR_KEYWORD
11731179
elif self.keyword_only:
11741180
kind = inspect.Parameter.KEYWORD_ONLY

0 commit comments

Comments
 (0)