Skip to content

Commit 21669a0

Browse files
committed
Add duplicate keyword argument error
Fixes RustPython#116
1 parent 51c3f71 commit 21669a0

File tree

4 files changed

+27
-0
lines changed

4 files changed

+27
-0
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

parser/src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub enum LexicalErrorType {
2121
UnicodeError,
2222
NestingError,
2323
PositionalArgumentError,
24+
DuplicateKeywordArgumentError,
2425
UnrecognizedToken { tok: char },
2526
FStringError(FStringErrorType),
2627
OtherError(String),
@@ -33,6 +34,9 @@ impl fmt::Display for LexicalErrorType {
3334
LexicalErrorType::FStringError(error) => write!(f, "Got error in f-string: {}", error),
3435
LexicalErrorType::UnicodeError => write!(f, "Got unexpected unicode"),
3536
LexicalErrorType::NestingError => write!(f, "Got unexpected nesting"),
37+
LexicalErrorType::DuplicateKeywordArgumentError => {
38+
write!(f, "keyword argument repeated")
39+
}
3640
LexicalErrorType::PositionalArgumentError => {
3741
write!(f, "positional argument follows keyword argument")
3842
}

parser/src/function.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashSet;
2+
13
use crate::ast;
24
use crate::error::{LexicalError, LexicalErrorType};
35

@@ -6,9 +8,22 @@ type FunctionArgument = (Option<Option<String>>, ast::Expression);
68
pub fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ast::ArgumentList, LexicalError> {
79
let mut args = vec![];
810
let mut keywords = vec![];
11+
12+
let mut keyword_names = HashSet::with_capacity(func_args.len());
913
for (name, value) in func_args {
1014
match name {
1115
Some(n) => {
16+
if let Some(keyword_name) = n.clone() {
17+
if keyword_names.contains(&keyword_name) {
18+
return Err(LexicalError {
19+
error: LexicalErrorType::DuplicateKeywordArgumentError,
20+
location: value.location.clone(),
21+
});
22+
}
23+
24+
keyword_names.insert(keyword_name.clone());
25+
}
26+
1227
keywords.push(ast::Keyword { name: n, value });
1328
}
1429
None => {

tests/snippets/function_args.py

+7
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,10 @@ def func(**kwargs):
9595

9696
kwargs = func(a=1, b=2, c=3)
9797
assert kwargs == [('a', 1), ('b', 2), ('c', 3)]
98+
99+
100+
def inc(n):
101+
return n + 1
102+
103+
with assert_raises(SyntaxError):
104+
exec("inc(n=1, n=2)")

0 commit comments

Comments
 (0)