diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-06-23 06:19:16 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-06-23 06:19:16 (GMT) |
commit | ad1a18b78ef87957a716af47e4c4f125e85565d0 (patch) | |
tree | ec93d18836134009e0cc3057c287566bc93a6fbf | |
parent | be9d10edbb9ca400d73012e9d0a1b068e0f74d14 (diff) | |
download | cpython-ad1a18b78ef87957a716af47e4c4f125e85565d0.zip cpython-ad1a18b78ef87957a716af47e4c4f125e85565d0.tar.gz cpython-ad1a18b78ef87957a716af47e4c4f125e85565d0.tar.bz2 |
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.
-rw-r--r-- | Python/ceval.c | 7 | ||||
-rw-r--r-- | Python/compile.c | 35 |
2 files changed, 17 insertions, 25 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index d334775..6a1ba50 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -166,6 +166,13 @@ gen_iternext(genobject *gen) Py_XDECREF(f->f_back); 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; } diff --git a/Python/compile.c b/Python/compile.c index 843cf09..2ce7487 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2639,20 +2639,14 @@ com_return_stmt(struct compiling *c, node *n) com_error(c, PyExc_SyntaxError, "'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); + 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); } @@ -3711,19 +3705,10 @@ compile_funcdef(struct compiling *c, node *n) c->c_infunction = 1; 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); - } + com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None)); + com_push(c, 1); + com_addbyte(c, RETURN_VALUE); + com_pop(c, 1); } static void |