]> granicus.if.org Git - python/commitdiff
Bug #1520864 (again): unpacking singleton tuples in list comprehensions and
authorNeal Norwitz <nnorwitz@gmail.com>
Tue, 5 Sep 2006 03:56:01 +0000 (03:56 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Tue, 5 Sep 2006 03:56:01 +0000 (03:56 +0000)
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.

Lib/test/test_grammar.py
Misc/NEWS
Python/ast.c
Python/import.c

index f16086734371ad637c6e0b2a842565aa91c4e0c9..c39e41699e9021f720b9e7b74a885715bfe070de 100644 (file)
@@ -825,6 +825,10 @@ verify([(i,j) for i in range(10) for j in range(5)] == list(g))
 verify([ x for x in range(10) if x % 2 if x % 3 ], [1, 5, 7])
 verify((x for x in range(10) if x % 2 if x % 3), [1, 5, 7])
 
+# Verify unpacking single element tuples in listcomp/genexp.
+vereq([x for x, in [(4,), (5,), (6,)]], [4, 5, 6])
+vereq(list(x for x, in [(7,), (8,), (9,)]), [7, 8, 9])
+
 # Test ifelse expressions in various cases
 def _checkeval(msg, ret):
     "helper to check that evaluation of expressions is done correctly"
index 394d9211ee82b61bb0d7fcb62c4311efdbc98b48..6bb2f97bea70db92b3b284a5ae93e2aee1395290 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -30,6 +30,11 @@ Core and builtins
 - The return tuple from str.rpartition(sep) is (tail, sep, head) where
   head is the original string if sep was not found.
 
+- Bug #1520864: unpacking singleton tuples in list comprehensions and
+  generator expressions (x for x, in ... ) works again.  Fixing this problem
+  required changing the .pyc magic number.  This means that .pyc files
+  generated before 2.5c2 will be regenerated.
+
 
 Library
 -------
index b356192d8929191f86a712924682618432725fe0..4d0b991c2cf34b4b9271e57862afefbb81dff1cd 100644 (file)
@@ -983,17 +983,21 @@ ast_for_listcomp(struct compiling *c, const node *n)
        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 @@ ast_for_genexp(struct compiling *c, const node *n)
         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
index da9de8b64fd3e7372708d7abc52de2811be67853..a0c5055142bce0c2da8d855cd002533d895307d0 100644 (file)
@@ -64,9 +64,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
        Python 2.5b3: 62111 (fix wrong code: x += yield)
        Python 2.5c1: 62121 (fix wrong lnotab with for loops and
                                    storing constants that should have been removed)
+       Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
 .
 */
-#define MAGIC (62121 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (62131 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the