mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	bpo-40147: Move the check for duplicate keywords to the compiler (GH-19289)
This commit is contained in:
		
							parent
							
								
									bd6a4c3d72
								
							
						
					
					
						commit
						254ec78341
					
				
					 4 changed files with 32 additions and 12 deletions
				
			
		| 
						 | 
					@ -128,7 +128,7 @@
 | 
				
			||||||
    ...
 | 
					    ...
 | 
				
			||||||
    Traceback (most recent call last):
 | 
					    Traceback (most recent call last):
 | 
				
			||||||
    [...]
 | 
					    [...]
 | 
				
			||||||
    SyntaxError: keyword argument repeated
 | 
					    SyntaxError: keyword argument repeated: metaclass
 | 
				
			||||||
    >>>
 | 
					    >>>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Another way.
 | 
					Another way.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -588,7 +588,7 @@
 | 
				
			||||||
>>> f(a=23, a=234)
 | 
					>>> f(a=23, a=234)
 | 
				
			||||||
Traceback (most recent call last):
 | 
					Traceback (most recent call last):
 | 
				
			||||||
   ...
 | 
					   ...
 | 
				
			||||||
SyntaxError: keyword argument repeated
 | 
					SyntaxError: keyword argument repeated: a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
>>> {1, 2, 3} = 42
 | 
					>>> {1, 2, 3} = 42
 | 
				
			||||||
Traceback (most recent call last):
 | 
					Traceback (most recent call last):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								Python/ast.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								Python/ast.c
									
										
									
									
									
								
							| 
						 | 
					@ -3048,8 +3048,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                /* a keyword argument */
 | 
					                /* a keyword argument */
 | 
				
			||||||
                keyword_ty kw;
 | 
					                keyword_ty kw;
 | 
				
			||||||
                identifier key, tmp;
 | 
					                identifier key;
 | 
				
			||||||
                int k;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // To remain LL(1), the grammar accepts any test (basically, any
 | 
					                // To remain LL(1), the grammar accepts any test (basically, any
 | 
				
			||||||
                // expression) in the keyword slot of a call site.  So, we need
 | 
					                // 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,
 | 
				
			||||||
                if (forbidden_name(c, key, chch, 1)) {
 | 
					                if (forbidden_name(c, key, chch, 1)) {
 | 
				
			||||||
                    return NULL;
 | 
					                    return NULL;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                for (k = 0; k < nkeywords; k++) {
 | 
					 | 
				
			||||||
                    tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg;
 | 
					 | 
				
			||||||
                    if (tmp && !PyUnicode_Compare(tmp, key)) {
 | 
					 | 
				
			||||||
                        ast_error(c, chch,
 | 
					 | 
				
			||||||
                                  "keyword argument repeated");
 | 
					 | 
				
			||||||
                        return NULL;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                e = ast_for_expr(c, CHILD(ch, 2));
 | 
					                e = ast_for_expr(c, CHILD(ch, 2));
 | 
				
			||||||
                if (!e)
 | 
					                if (!e)
 | 
				
			||||||
                    return NULL;
 | 
					                    return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4049,6 +4049,31 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e)
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					validate_keywords(struct compiler *c, asdl_seq* keywords) {
 | 
				
			||||||
 | 
					    int nkeywords = asdl_seq_LEN(keywords);
 | 
				
			||||||
 | 
					    for (int i = 0; i < nkeywords; i++) {
 | 
				
			||||||
 | 
					        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
 | 
				
			||||||
 | 
					        if (key->arg == NULL) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (int j = i+1; j < nkeywords; j++) {
 | 
				
			||||||
 | 
					            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
 | 
				
			||||||
 | 
					            if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
 | 
				
			||||||
 | 
					                PyObject *msg = PyUnicode_FromFormat("keyword argument repeated: %U", key->arg);
 | 
				
			||||||
 | 
					                if (msg == NULL) {
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                c->u->u_col_offset = other->col_offset;
 | 
				
			||||||
 | 
					                compiler_error(c, PyUnicode_AsUTF8(msg));
 | 
				
			||||||
 | 
					                Py_DECREF(msg);
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
compiler_call(struct compiler *c, expr_ty e)
 | 
					compiler_call(struct compiler *c, expr_ty e)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -4165,6 +4190,10 @@ compiler_call_helper(struct compiler *c,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Py_ssize_t i, nseen, nelts, nkwelts;
 | 
					    Py_ssize_t i, nseen, nelts, nkwelts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (validate_keywords(c, keywords) == -1) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nelts = asdl_seq_LEN(args);
 | 
					    nelts = asdl_seq_LEN(args);
 | 
				
			||||||
    nkwelts = asdl_seq_LEN(keywords);
 | 
					    nkwelts = asdl_seq_LEN(keywords);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue