From 52ce4379513f46f6a2c6ba2762004790a76b2bdf Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Tue, 27 Dec 2022 01:48:05 -0800 Subject: [PATCH] Prohibit starred arguments after double-starred arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPython prohibits ‘f(**kwargs, *args)’; we should too. Signed-off-by: Anders Kaseorg --- Lib/test/test_syntax.py | 2 -- compiler/parser/src/error.rs | 7 +++++++ compiler/parser/src/function.rs | 11 ++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index cc51d24c9..db09c4b5c 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -1453,8 +1453,6 @@ class SyntaxTestCase(unittest.TestCase): "positional argument follows " "keyword argument unpacking") - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_kwargs_last3(self): self._check_error("int(**{'base': 10}, *['2'])", "iterable argument unpacking follows " diff --git a/compiler/parser/src/error.rs b/compiler/parser/src/error.rs index 89f536682..47096a544 100644 --- a/compiler/parser/src/error.rs +++ b/compiler/parser/src/error.rs @@ -22,6 +22,7 @@ pub enum LexicalErrorType { TabsAfterSpaces, DefaultArgumentError, PositionalArgumentError, + UnpackedArgumentError, DuplicateKeywordArgumentError, UnrecognizedToken { tok: char }, FStringError(FStringErrorType), @@ -55,6 +56,12 @@ impl fmt::Display for LexicalErrorType { LexicalErrorType::PositionalArgumentError => { write!(f, "positional argument follows keyword argument") } + LexicalErrorType::UnpackedArgumentError => { + write!( + f, + "iterable argument unpacking follows keyword argument unpacking" + ) + } LexicalErrorType::UnrecognizedToken { tok } => { write!(f, "Got unexpected token {tok}") } diff --git a/compiler/parser/src/function.rs b/compiler/parser/src/function.rs index 0cc934fb4..466211304 100644 --- a/compiler/parser/src/function.rs +++ b/compiler/parser/src/function.rs @@ -55,6 +55,7 @@ pub fn parse_args(func_args: Vec) -> Result { @@ -67,6 +68,8 @@ pub fn parse_args(func_args: Vec) -> Result) -> Result { - // Allow starred args after keyword arguments. + // Allow starred arguments after keyword arguments but + // not after double-starred arguments. if !keywords.is_empty() && !is_starred(&value) { return Err(LexicalError { error: LexicalErrorType::PositionalArgumentError, location: value.location, }); + } else if double_starred { + return Err(LexicalError { + error: LexicalErrorType::UnpackedArgumentError, + location: value.location, + }); } args.push(value);