diff Python/ast.c @ 39753:8dcb882ec3e1 legacy-trunk

Bug #1520864 (again): unpacking singleton tuples in list comprehensions and generator expressions (x for x, in ... ) works again. Sigh, I only fixed for loops the first time, not list comps and genexprs too. I couldn't find any more unpacking cases where there is a similar bug lurking. This code should be refactored to eliminate the duplication. I'm sure the listcomp/genexpr code can be refactored. I'm not sure if the for loop can re-use any of the same code though. Will backport to 2.5 (the only place it matters).
author Neal Norwitz <nnorwitz@gmail.com>
date Tue, 05 Sep 2006 03:53:08 +0000
parents e11caad7e029
children dec7d993b68f c591d9954fb3
line wrap: on
line diff
--- a/Python/ast.c	Tue Sep 05 02:57:01 2006 +0000
+++ b/Python/ast.c	Tue Sep 05 03:53:08 2006 +0000
@@ -983,17 +983,21 @@
 	comprehension_ty lc;
 	asdl_seq *t;
         expr_ty expression;
+        node *for_ch;
 
 	REQ(ch, list_for);
 
-	t = ast_for_exprlist(c, CHILD(ch, 1), Store);
+        for_ch = CHILD(ch, 1);
+        t = ast_for_exprlist(c, for_ch, Store);
         if (!t)
             return NULL;
         expression = ast_for_testlist(c, CHILD(ch, 3));
         if (!expression)
             return NULL;
 
-	if (asdl_seq_LEN(t) == 1)
+        /* Check the # of children rather than the length of t, since
+           [x for x, in ... ] has 1 element in t, but still requires a Tuple. */
+	if (NCH(for_ch) == 1)
 	    lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,
                                c->c_arena);
 	else
@@ -1129,17 +1133,21 @@
         comprehension_ty ge;
         asdl_seq *t;
         expr_ty expression;
+        node *for_ch;
         
         REQ(ch, gen_for);
         
-        t = ast_for_exprlist(c, CHILD(ch, 1), Store);
+        for_ch = CHILD(ch, 1);
+        t = ast_for_exprlist(c, for_ch, Store);
         if (!t)
             return NULL;
         expression = ast_for_expr(c, CHILD(ch, 3));
         if (!expression)
             return NULL;
 
-        if (asdl_seq_LEN(t) == 1)
+        /* Check the # of children rather than the length of t, since
+           (x for x, in ...) has 1 element in t, but still requires a Tuple. */
+        if (NCH(for_ch) == 1)
             ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,
                                NULL, c->c_arena);
         else