Skip to content
Open
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
61 changes: 25 additions & 36 deletions Lib/test/test_clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,27 +358,13 @@ def test_vararg_after_star(self):
self.expect_failure(block, err, lineno=6)

def test_double_star_after_var_keyword(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be renamed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, is there a test for a single ** without name?

err = "Function 'my_test_func' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = "parameters cannot follow var-keyword parameter: 'invalid_arg: object'"
block = """
/*[clinic input]
my_test_func

pos_arg: object
**kwds: dict
**
[clinic start generated code]*/
"""
self.expect_failure(block, err, lineno=5)

def test_var_keyword_after_star(self):
err = "Function 'my_test_func' has an invalid parameter declaration: '**'"
block = """
/*[clinic input]
my_test_func

pos_arg: object
**
**kwds: dict
invalid_arg: object
[clinic start generated code]*/
"""
self.expect_failure(block, err, lineno=5)
Expand Down Expand Up @@ -1644,11 +1630,6 @@ def test_disallowed_grouping__must_be_position_only(self):
[
a: object
]
""", """
with_kwds
[
**kwds: dict
]
Comment on lines -1647 to -1651
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add also a test for var-positional?

            with_varpos
                [
                *args: tuple
                ]

If it is an error and has not yet been tested.

If it is an error, and the error message is the same as for keyword arguments here, then it would be reasonable to make the error message for var-keyword the same. Otherwise we can leave a discrepancy.

""")
err = (
"You cannot use optional groups ('[' and ']') unless all "
Expand Down Expand Up @@ -2036,38 +2017,40 @@ def test_slash_after_var_keyword(self):
block = """
module foo
foo.bar
x: int
y: int
**kwds: dict
z: int
/
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = "parameters cannot follow var-keyword parameter: '/'"
self.expect_failure(block, err)

def test_star_after_var_keyword(self):
block = """
module foo
foo.bar
x: int
y: int
**kwds: dict
z: int
*
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = "parameters cannot follow var-keyword parameter: '*'"
self.expect_failure(block, err)

def test_parameter_after_var_keyword(self):
block = """
module foo
foo.bar
x: int
y: int
**kwds: dict
z: int
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = "parameters cannot follow var-keyword parameter: 'z: int'"
self.expect_failure(block, err)

def test_group_with_var_keyword(self):
block = """
with_kwds
[
**kwds: dict
]
"""
err = "parameters cannot follow var-keyword parameter: ']'"
self.expect_failure(block, err)

def test_depr_star_must_come_after_slash(self):
Expand Down Expand Up @@ -2159,7 +2142,7 @@ def test_parameters_no_more_than_one_vararg(self):
self.expect_failure(block, err, lineno=3)

def test_parameters_no_more_than_one_var_keyword(self):
err = "Encountered parameter line when not expecting parameters: **var_keyword_2: dict"
err = "parameters cannot follow var-keyword parameter: '**var_keyword_2: dict'"
block = """
module foo
foo.bar
Expand Down Expand Up @@ -2714,7 +2697,9 @@ def test_var_keyword_with_pos_or_kw(self):
x: int
**kwds: dict
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = ("Function 'bar' uses a var-keyword parameter and other "
"non-positional parameters, which Argument Clinic does "
"not currently support: '**kwds: dict'")
self.expect_failure(block, err)

def test_var_keyword_with_kw_only(self):
Expand All @@ -2727,7 +2712,9 @@ def test_var_keyword_with_kw_only(self):
y: int
**kwds: dict
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = ("Function 'bar' uses a var-keyword parameter and other "
"non-positional parameters, which Argument Clinic does "
"not currently support: '**kwds: dict'")
self.expect_failure(block, err)

def test_var_keyword_with_pos_or_kw_and_kw_only(self):
Expand All @@ -2741,7 +2728,9 @@ def test_var_keyword_with_pos_or_kw_and_kw_only(self):
z: int
**kwds: dict
"""
err = "Function 'bar' has an invalid parameter declaration (**kwargs?): '**kwds: dict'"
err = ("Function 'bar' uses a var-keyword parameter and other "
"non-positional parameters, which Argument Clinic does "
"not currently support: '**kwds: dict'")
self.expect_failure(block, err)

def test_allow_negative_accepted_by_py_ssize_t_converter_only(self):
Expand Down
18 changes: 6 additions & 12 deletions Tools/clinic/libclinic/dsl_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,9 @@ def state_parameter(self, line: str) -> None:
line = match[1]
version = self.parse_version(match[2])

if not self.expecting_parameters:
fail(f'parameters cannot follow var-keyword parameter: {line!r}')

func = self.function
match line:
case '*':
Expand All @@ -878,10 +881,6 @@ def state_parameter(self, line: str) -> None:
def parse_parameter(self, line: str) -> None:
assert self.function is not None

if not self.expecting_parameters:
fail('Encountered parameter line when not expecting '
f'parameters: {line}')

match self.parameter_state:
case ParamState.START | ParamState.REQUIRED:
self.to_required()
Expand Down Expand Up @@ -932,8 +931,9 @@ def parse_parameter(self, line: str) -> None:
for p in self.function.parameters.values()
)
if has_non_positional_param:
fail(f"Function {self.function.name!r} has an "
f"invalid parameter declaration (**kwargs?): {line!r}")
fail(f'Function {self.function.name!r} uses a var-keyword parameter '
f'and other non-positional parameters, which Argument Clinic '
f'does not currently support: {line!r}')
is_var_keyword = True
parameter = function_args.kwarg
else:
Expand Down Expand Up @@ -1182,9 +1182,6 @@ def parse_star(self, function: Function, version: VersionTuple | None) -> None:
The 'version' parameter signifies the future version from which
the marker will take effect (None means it is already in effect).
"""
if not self.expecting_parameters:
fail("Encountered '*' when not expecting parameters")

if version is None:
self.check_previous_star()
self.check_remaining_star()
Expand Down Expand Up @@ -1240,9 +1237,6 @@ def parse_slash(self, function: Function, version: VersionTuple | None) -> None:
The 'version' parameter signifies the future version from which
the marker will take effect (None means it is already in effect).
"""
if not self.expecting_parameters:
fail("Encountered '/' when not expecting parameters")

if version is None:
if self.deprecated_keyword:
fail(f"Function {function.name!r}: '/' must precede '/ [from ...]'")
Expand Down
Loading