mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
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:
parent
be9d10edbb
commit
ad1a18b78e
2 changed files with 17 additions and 25 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
if (NCH(n) < 2) {
|
||||
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
|
||||
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);
|
||||
}
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue