Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 254ec78

Browse files
authored
bpo-40147: Move the check for duplicate keywords to the compiler (GH-19289)
1 parent bd6a4c3 commit 254ec78

4 files changed

Lines changed: 32 additions & 12 deletions

File tree

Lib/test/test_metaclass.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
...
129129
Traceback (most recent call last):
130130
[...]
131-
SyntaxError: keyword argument repeated
131+
SyntaxError: keyword argument repeated: metaclass
132132
>>>
133133
134134
Another way.

Lib/test/test_syntax.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@
588588
>>> f(a=23, a=234)
589589
Traceback (most recent call last):
590590
...
591-
SyntaxError: keyword argument repeated
591+
SyntaxError: keyword argument repeated: a
592592
593593
>>> {1, 2, 3} = 42
594594
Traceback (most recent call last):

Python/ast.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,8 +3048,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
30483048
else {
30493049
/* a keyword argument */
30503050
keyword_ty kw;
3051-
identifier key, tmp;
3052-
int k;
3051+
identifier key;
30533052

30543053
// To remain LL(1), the grammar accepts any test (basically, any
30553054
// expression) in the keyword slot of a call site. So, we need
@@ -3093,14 +3092,6 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
30933092
if (forbidden_name(c, key, chch, 1)) {
30943093
return NULL;
30953094
}
3096-
for (k = 0; k < nkeywords; k++) {
3097-
tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg;
3098-
if (tmp && !PyUnicode_Compare(tmp, key)) {
3099-
ast_error(c, chch,
3100-
"keyword argument repeated");
3101-
return NULL;
3102-
}
3103-
}
31043095
e = ast_for_expr(c, CHILD(ch, 2));
31053096
if (!e)
31063097
return NULL;

Python/compile.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,6 +4049,31 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
40494049
return 1;
40504050
}
40514051

4052+
static int
4053+
validate_keywords(struct compiler *c, asdl_seq* keywords) {
4054+
int nkeywords = asdl_seq_LEN(keywords);
4055+
for (int i = 0; i < nkeywords; i++) {
4056+
keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4057+
if (key->arg == NULL) {
4058+
continue;
4059+
}
4060+
for (int j = i+1; j < nkeywords; j++) {
4061+
keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4062+
if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
4063+
PyObject *msg = PyUnicode_FromFormat("keyword argument repeated: %U", key->arg);
4064+
if (msg == NULL) {
4065+
return -1;
4066+
}
4067+
c->u->u_col_offset = other->col_offset;
4068+
compiler_error(c, PyUnicode_AsUTF8(msg));
4069+
Py_DECREF(msg);
4070+
return -1;
4071+
}
4072+
}
4073+
}
4074+
return 0;
4075+
}
4076+
40524077
static int
40534078
compiler_call(struct compiler *c, expr_ty e)
40544079
{
@@ -4165,6 +4190,10 @@ compiler_call_helper(struct compiler *c,
41654190
{
41664191
Py_ssize_t i, nseen, nelts, nkwelts;
41674192

4193+
if (validate_keywords(c, keywords) == -1) {
4194+
return 0;
4195+
}
4196+
41684197
nelts = asdl_seq_LEN(args);
41694198
nkwelts = asdl_seq_LEN(keywords);
41704199

0 commit comments

Comments
 (0)