diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index a184a8be3c6..ee36413de7c 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1497,22 +1497,55 @@ And a more sane, but still weird usage: +A yield expression with augmented assignment. + +>>> def coroutine(seq): +... count = 0 +... while count < 200: +... count += yield +... seq.append(count) +>>> seq = [] +>>> c = coroutine(seq) +>>> c.next() +>>> print seq +[] +>>> c.send(10) +>>> print seq +[10] +>>> c.send(10) +>>> print seq +[10, 20] +>>> c.send(10) +>>> print seq +[10, 20, 30] + + Check some syntax errors for yield expressions: >>> f=lambda: (yield 1),(yield 2) Traceback (most recent call last): ... -SyntaxError: 'yield' outside function (, line 1) +SyntaxError: 'yield' outside function (, line 1) >>> def f(): return lambda x=(yield): 1 Traceback (most recent call last): ... -SyntaxError: 'return' with argument inside generator (, line 1) +SyntaxError: 'return' with argument inside generator (, line 1) >>> def f(): x = yield = y Traceback (most recent call last): ... -SyntaxError: assignment to yield expression not possible (, line 1) +SyntaxError: assignment to yield expression not possible (, line 1) + +>>> def f(): (yield bar) = y +Traceback (most recent call last): + ... +SyntaxError: can't assign to yield expression (, line 1) + +>>> def f(): (yield bar) += y +Traceback (most recent call last): + ... +SyntaxError: augmented assignment to yield expression not possible (, line 1) Now check some throw() conditions: diff --git a/Misc/ACKS b/Misc/ACKS index 5998bca41e7..d35fb703835 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -624,6 +624,7 @@ Laurence Tratt John Tromp Jason Trowbridge Anthony Tuininga +Christopher Tur Lesniewski-Laas Stephen Turner Bill Tutt Doobee R. Tzeck diff --git a/Misc/NEWS b/Misc/NEWS index 19740de2a45..141850db7ad 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,9 @@ What's New in Python 2.5 beta 3? Core and builtins ----------------- +- Patch #1531113: Fix augmented assignment with yield expressions. + Also fix a SystemError when trying to assign to yield expressions. + - Bug #1529871: The speed enhancement patch #921466 broke Python's compliance with PEP 302. This was fixed by adding an ``imp.NullImporter`` type that is used in ``sys.path_importer_cache`` to cache non-directory paths and avoid diff --git a/Python/ast.c b/Python/ast.c index 9180fd0d693..9e8d911a87a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -387,6 +387,9 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n) case GeneratorExp_kind: expr_name = "generator expression"; break; + case Yield_kind: + expr_name = "yield expression"; + break; case ListComp_kind: expr_name = "list comprehension"; break; @@ -1928,12 +1931,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) operator_ty newoperator; node *ch = CHILD(n, 0); - if (TYPE(ch) == testlist) - expr1 = ast_for_testlist(c, ch); - else - expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch), n->n_col_offset, - c->c_arena); - + expr1 = ast_for_testlist(c, ch); if (!expr1) return NULL; /* TODO(nas): Remove duplicated error checks (set_context does it) */ @@ -1942,6 +1940,10 @@ ast_for_expr_stmt(struct compiling *c, const node *n) ast_error(ch, "augmented assignment to generator " "expression not possible"); return NULL; + case Yield_kind: + ast_error(ch, "augmented assignment to yield " + "expression not possible"); + return NULL; case Name_kind: { const char *var_name = PyString_AS_STRING(expr1->v.Name.id); if (var_name[0] == 'N' && !strcmp(var_name, "None")) { @@ -1964,7 +1966,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) if (TYPE(ch) == testlist) expr2 = ast_for_testlist(c, ch); else - expr2 = Yield(ast_for_expr(c, ch), LINENO(ch), ch->n_col_offset, c->c_arena); + expr2 = ast_for_expr(c, ch); if (!expr2) return NULL; diff --git a/Python/import.c b/Python/import.c index ef64b21b383..26664ce7c88 100644 --- a/Python/import.c +++ b/Python/import.c @@ -60,10 +60,11 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *); Python 2.5a0: 62081 (ast-branch) Python 2.5a0: 62091 (with) Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) - Python 2.5c1: 62101 (fix wrong code: for x, in ...) + Python 2.5b3: 62101 (fix wrong code: for x, in ...) + Python 2.5b3: 62111 (fix wrong code: x += yield) . */ -#define MAGIC (62101 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (62111 | ((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