@@ -2815,29 +2815,56 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func, bool allowgen)
28152815 identifier key , tmp ;
28162816 int k ;
28172817
2818- /* chch is test, but must be an identifier? */
2819- e = ast_for_expr (c , chch );
2820- if (!e )
2821- return NULL ;
2822- /* f(lambda x: x[0] = 3) ends up getting parsed with
2823- * LHS test = lambda x: x[0], and RHS test = 3.
2824- * SF bug 132313 points out that complaining about a keyword
2825- * then is very confusing.
2826- */
2827- if (e -> kind == Lambda_kind ) {
2818+ // To remain LL(1), the grammar accepts any test (basically, any
2819+ // expression) in the keyword slot of a call site. So, we need
2820+ // to manually enforce that the keyword is a NAME here.
2821+ static const int name_tree [] = {
2822+ test ,
2823+ or_test ,
2824+ and_test ,
2825+ not_test ,
2826+ comparison ,
2827+ expr ,
2828+ xor_expr ,
2829+ and_expr ,
2830+ shift_expr ,
2831+ arith_expr ,
2832+ term ,
2833+ factor ,
2834+ power ,
2835+ atom_expr ,
2836+ atom ,
2837+ 0 ,
2838+ };
2839+ node * expr_node = chch ;
2840+ for (int i = 0 ; name_tree [i ]; i ++ ) {
2841+ if (TYPE (expr_node ) != name_tree [i ])
2842+ break ;
2843+ if (NCH (expr_node ) != 1 )
2844+ break ;
2845+ expr_node = CHILD (expr_node , 0 );
2846+ }
2847+ if (TYPE (expr_node ) == lambdef ) {
2848+ // f(lambda x: x[0] = 3) ends up getting parsed with LHS
2849+ // test = lambda x: x[0], and RHS test = 3. Issue #132313
2850+ // points out that complaining about a keyword then is very
2851+ // confusing.
28282852 ast_error (c , chch ,
28292853 "lambda cannot contain assignment" );
28302854 return NULL ;
28312855 }
2832- else if (e -> kind != Name_kind ) {
2856+ else if (TYPE ( expr_node ) != NAME ) {
28332857 ast_error (c , chch ,
2834- "keyword can't be an expression" );
2858+ "keyword can't be an expression" );
2859+ return NULL ;
2860+ }
2861+ key = new_identifier (STR (expr_node ), c );
2862+ if (key == NULL ) {
28352863 return NULL ;
28362864 }
2837- else if (forbidden_name (c , e -> v . Name . id , ch , 1 )) {
2865+ if (forbidden_name (c , key , chch , 1 )) {
28382866 return NULL ;
28392867 }
2840- key = e -> v .Name .id ;
28412868 for (k = 0 ; k < nkeywords ; k ++ ) {
28422869 tmp = ((keyword_ty )asdl_seq_GET (keywords , k ))-> arg ;
28432870 if (tmp && !PyUnicode_Compare (tmp , key )) {
0 commit comments