mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	Patch #1531113: Fix augmented assignment with yield expressions.
Also fix a SystemError when trying to assign to yield expressions.
This commit is contained in:
		
							parent
							
								
									33c3e29fce
								
							
						
					
					
						commit
						0d62a06206
					
				
					 5 changed files with 52 additions and 12 deletions
				
			
		| 
						 | 
				
			
			@ -1497,22 +1497,55 @@ And a more sane, but still weird usage:
 | 
			
		|||
<type 'generator'>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 (<doctest test.test_generators.__test__.coroutine[10]>, line 1)
 | 
			
		||||
SyntaxError: 'yield' outside function (<doctest test.test_generators.__test__.coroutine[21]>, line 1)
 | 
			
		||||
 | 
			
		||||
>>> def f(): return lambda x=(yield): 1
 | 
			
		||||
Traceback (most recent call last):
 | 
			
		||||
  ...
 | 
			
		||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.coroutine[11]>, line 1)
 | 
			
		||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.coroutine[22]>, line 1)
 | 
			
		||||
 | 
			
		||||
>>> def f(): x = yield = y
 | 
			
		||||
Traceback (most recent call last):
 | 
			
		||||
  ...
 | 
			
		||||
SyntaxError: assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[12]>, line 1)
 | 
			
		||||
SyntaxError: assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[23]>, line 1)
 | 
			
		||||
 | 
			
		||||
>>> def f(): (yield bar) = y
 | 
			
		||||
Traceback (most recent call last):
 | 
			
		||||
  ...
 | 
			
		||||
SyntaxError: can't assign to yield expression (<doctest test.test_generators.__test__.coroutine[24]>, line 1)
 | 
			
		||||
 | 
			
		||||
>>> def f(): (yield bar) += y
 | 
			
		||||
Traceback (most recent call last):
 | 
			
		||||
  ...
 | 
			
		||||
SyntaxError: augmented assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[25]>, line 1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Now check some throw() conditions:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -624,6 +624,7 @@ Laurence Tratt
 | 
			
		|||
John Tromp
 | 
			
		||||
Jason Trowbridge
 | 
			
		||||
Anthony Tuininga
 | 
			
		||||
Christopher Tur Lesniewski-Laas
 | 
			
		||||
Stephen Turner
 | 
			
		||||
Bill Tutt
 | 
			
		||||
Doobee R. Tzeck
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								Python/ast.c
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue