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.
This commit is contained in:
Tim Peters 2001-06-23 06:19:16 +00:00
parent be9d10edbb
commit ad1a18b78e
2 changed files with 17 additions and 25 deletions

View file

@ -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;
}