Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ad1a18b

Browse files
committed
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.
1 parent be9d10e commit ad1a18b

2 files changed

Lines changed: 17 additions & 25 deletions

File tree

Python/ceval.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ gen_iternext(genobject *gen)
166166
Py_XDECREF(f->f_back);
167167
f->f_back = NULL;
168168

169+
/* If the generator just returned (as opposed to yielding), signal
170+
* that the generator is exhausted. */
171+
if (result == Py_None && f->f_stacktop == NULL) {
172+
Py_DECREF(result);
173+
result = NULL;
174+
}
175+
169176
return result;
170177
}
171178

Python/compile.c

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,20 +2639,14 @@ com_return_stmt(struct compiling *c, node *n)
26392639
com_error(c, PyExc_SyntaxError,
26402640
"'return' with argument inside generator");
26412641
}
2642-
com_addoparg(c, LOAD_CONST,
2643-
com_addconst(c, PyExc_StopIteration));
2644-
com_push(c, 1);
2645-
com_addoparg(c, RAISE_VARARGS, 1);
26462642
}
2647-
else {
2648-
if (NCH(n) < 2) {
2649-
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
2650-
com_push(c, 1);
2651-
}
2652-
else
2653-
com_node(c, CHILD(n, 1));
2654-
com_addbyte(c, RETURN_VALUE);
2643+
if (NCH(n) < 2) {
2644+
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
2645+
com_push(c, 1);
26552646
}
2647+
else
2648+
com_node(c, CHILD(n, 1));
2649+
com_addbyte(c, RETURN_VALUE);
26562650
com_pop(c, 1);
26572651
}
26582652

@@ -3711,19 +3705,10 @@ compile_funcdef(struct compiling *c, node *n)
37113705
c->c_infunction = 1;
37123706
com_node(c, CHILD(n, 4));
37133707
c->c_infunction = 0;
3714-
if (c->c_flags & CO_GENERATOR) {
3715-
com_addoparg(c, LOAD_CONST,
3716-
com_addconst(c, PyExc_StopIteration));
3717-
com_push(c, 1);
3718-
com_addoparg(c, RAISE_VARARGS, 1);
3719-
com_pop(c, 1);
3720-
}
3721-
else {
3722-
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
3723-
com_push(c, 1);
3724-
com_addbyte(c, RETURN_VALUE);
3725-
com_pop(c, 1);
3726-
}
3708+
com_addoparg(c, LOAD_CONST, com_addconst(c, Py_None));
3709+
com_push(c, 1);
3710+
com_addbyte(c, RETURN_VALUE);
3711+
com_pop(c, 1);
37273712
}
37283713

37293714
static void

0 commit comments

Comments
 (0)