Skip to content

Commit ecf8e44

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

File tree

4 files changed

+24
-0
lines changed

4 files changed

+24
-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

+12
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,19 @@ 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 keyword_names.contains(&n) {
17+
return Err(LexicalError {
18+
error: LexicalErrorType::DuplicateKeywordArgumentError,
19+
location: value.location.clone(),
20+
});
21+
}
22+
23+
keyword_names.insert(n.clone());
1224
keywords.push(ast::Keyword { name: n, value });
1325
}
1426
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)