[Python-checkins] r51729 - in python/trunk: Lib/test/test_grammar.py Misc/NEWS Python/ast.c Python/import.c
neal.norwitz
python-checkins at python.org
Tue Sep 5 05:53:09 CEST 2006
Author: neal.norwitz
Date: Tue Sep 5 05:53:08 2006
New Revision: 51729
Modified:
python/trunk/Lib/test/test_grammar.py
python/trunk/Misc/NEWS
python/trunk/Python/ast.c
python/trunk/Python/import.c
Log:
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).
Modified: python/trunk/Lib/test/test_grammar.py
==============================================================================
--- python/trunk/Lib/test/test_grammar.py (original)
+++ python/trunk/Lib/test/test_grammar.py Tue Sep 5 05:53:08 2006
@@ -825,6 +825,10 @@
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"
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Tue Sep 5 05:53:08 2006
@@ -22,6 +22,11 @@
- 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
-------
Modified: python/trunk/Python/ast.c
==============================================================================
--- python/trunk/Python/ast.c (original)
+++ python/trunk/Python/ast.c Tue Sep 5 05:53:08 2006
@@ -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
Modified: python/trunk/Python/import.c
==============================================================================
--- python/trunk/Python/import.c (original)
+++ python/trunk/Python/import.c Tue Sep 5 05:53:08 2006
@@ -64,9 +64,10 @@
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
More information about the Python-checkins
mailing list