[Python-checkins] CVS: python/dist/src/Python ceval.c,2.255,2.256 compile.c,2.203,2.204

Tim Peters tim_one@users.sourceforge.net
Fri, 22 Jun 2001 23:19:18 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv10949/python/dist/src/Python

Modified Files:
	ceval.c compile.c 
Log Message:
Change the semantics of "return" in generators, as discussed on the
Iterators list and Python-Dev; e.g., these all pass now:

def g1():
    try:
        return
    except:
        yield 1
assert list(g1()) == []

def g2():
    try:
        return
    finally:
        yield 1
assert list(g2()) == [1]

def g3():
    for i in range(3):
        yield None
    yield None
assert list(g3()) == [None] * 4

compile.c:  compile_funcdef and com_return_stmt:  Just van Rossum's patch
to compile the same code for "return" regardless of function type (this
goes back to the previous scheme of returning Py_None).

ceval.c:  gen_iternext:  take a return (but not a yield) of Py_None as
meaning the generator is exhausted.


Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.255
retrieving revision 2.256
diff -C2 -r2.255 -r2.256
*** ceval.c	2001/06/23 05:47:56	2.255
--- ceval.c	2001/06/23 06:19:16	2.256
***************
*** 167,170 ****
--- 167,177 ----
  	f->f_back = NULL;
  
+ 	/* If the generator just returned (as opposed to yielding), signal
+ 	 * that the generator is exhausted. */
+ 	if (result == Py_None && f->f_stacktop == NULL) {
+ 		Py_DECREF(result);
+ 		result = NULL;
+ 	}
+ 
  	return result;
  }

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.203
retrieving revision 2.204
diff -C2 -r2.203 -r2.204
*** compile.c	2001/06/23 02:07:08	2.203
--- compile.c	2001/06/23 06:19:16	2.204
***************
*** 2640,2657 ****
  				  "'return' with argument inside generator");
  		}
- 		com_addoparg(c, LOAD_CONST,
- 				com_addconst(c, PyExc_StopIteration));
- 		com_push(c, 1);
- 		com_addoparg(c, RAISE_VARARGS, 1);
  	}
! 	else {
! 		if (NCH(n) < 2) {
! 			com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 			com_push(c, 1);
! 		}
! 		else
! 			com_node(c, CHILD(n, 1));
! 		com_addbyte(c, RETURN_VALUE);
  	}
  	com_pop(c, 1);
  }
--- 2640,2651 ----
  				  "'return' with argument inside generator");
  		}
  	}
! 	if (NCH(n) < 2) {
! 		com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 		com_push(c, 1);
  	}
+ 	else
+ 		com_node(c, CHILD(n, 1));
+ 	com_addbyte(c, RETURN_VALUE);
  	com_pop(c, 1);
  }
***************
*** 3712,3728 ****
  	com_node(c, CHILD(n, 4));
  	c->c_infunction = 0;
! 	if (c->c_flags & CO_GENERATOR) {
! 		com_addoparg(c, LOAD_CONST,
! 				com_addconst(c, PyExc_StopIteration));
! 		com_push(c, 1);
! 		com_addoparg(c, RAISE_VARARGS, 1);
! 		com_pop(c, 1);
! 	}
! 	else {
! 		com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 		com_push(c, 1);
! 		com_addbyte(c, RETURN_VALUE);
! 		com_pop(c, 1);
! 	}
  }
  
--- 3706,3713 ----
  	com_node(c, CHILD(n, 4));
  	c->c_infunction = 0;
! 	com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
! 	com_push(c, 1);
! 	com_addbyte(c, RETURN_VALUE);
! 	com_pop(c, 1);
  }