I think nobody thought in advance this case (a lambda expression with
yield?), else it would have been forbidden. The lambda is roughly
equivalent to:
def anonymous():
return ((yield 666),(yield 777),(yield 888))
x = anonymous()
but *that* function is forbidden: a generator cannot contain a "return
something" statement. Writing it as a lambda expression, you are bypassing
the compiler check.
Those three None are the 3 yield values, combined into one tuple. You can
verify using send instead of next; the Nones are replaced by the received
values:
py> x = (lambda : ((yield 666),(yield 777),(yield 888)))()
py> x.send(None)
666
py> x.send(1)
777
py> x.send(2)
888
py> x.send(3)
(1, 2, 3)
That was the return in effect. As the function (or lambda) is exited, the
next try should raise StopIteration:
py> x.send(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Let's check with dis:
py> dis.dis(x.gi_frame.f_code)
1 0 LOAD_CONST 0 (666)
3 YIELD_VALUE
4 LOAD_CONST 1 (777)
7 YIELD_VALUE
8 LOAD_CONST 2 (888)
11 YIELD_VALUE
12 BUILD_TUPLE 3
15 RETURN_VALUE
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
x.next()
StopIteration
This time, the ((tuple) and None) is like saying "discard the tuple and
return None instead", and that fires the usual StopIteration.