[Python-Dev] Tricky way of of creating a generator via a comprehension expression

Ethan Furman ethan at stoneleaf.us
Wed Nov 22 16:18:10 EST 2017

On 11/22/2017 11:01 AM, Ivan Levkivskyi wrote:

> I think how to formulate these rules more "precisely" so that they will be all consistent even if there is a
> `yield` inside.
> The key idea is that neither comprehensions nor generator expressions should create a function scope surrounding the
> `expr` in (expr for ind in iterable) and [expr for ind in iterable].
> (this still can be some hidden implementation detail)
> So as Serhiy proposed in one of his first posts any comprehensions and generator expressions with `yield` are not valid
> outside functions.
> If such comprehension or generator expression is inside a function, then it makes it a generator, and all the `yield`s
> are yielded from that generator, for example:

Whether it's inside or outside a function should be irrelevant -- a comprehension / generator expression should have no 
influence on the type of the resulting function (and at least synchronous comprehensions / generator expressions should 
be able to live outside of a function).

> def fun_gen():
>      return list((yield i) for i in range(3))

The return says it's returning a list, so that's what it should be returning.

> should work as following:
> g = func_gen()
> g.send(42)
> 0
> g.send(43)
> 1
> g.send(44)
> 2
> try:
>      g.send(45)
> except StopIteration as e:
>      assert e.value  == [42, 43, 44]
> And exactly the same with
> def fun_comp():
>      [(yield i) for i in range(3)]
> I hope with this we can close the no-async part of the problem.
> Currently this is not how it works, and should be fixed. Do you agree?


NB: If we go with making yield inside a comprehension / generator expression a SyntaxError then this subthread can die.


More information about the Python-Dev mailing list