[Python-ideas] Change how Generator Expressions handle StopIteration

Ron Adam ron3200 at gmail.com
Thu Nov 6 15:24:13 CET 2014



On 11/06/2014 04:15 AM, Steven D'Aprano wrote:
> The current situation is simple to learn and understand:
>
> (1) Generator expressions*emit*  StopIteration when they are done:
>
> py> next(iter([]))
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> StopIteration

It's the "when they are done" part that's having the issue.  In some cases, 
they are never completely done because the StopIteration Error is handled 
incorrectly.  The reason this doesn't show up more is that most iterators 
only have one loop, which is exited and the generator ends causing a 
different StopIteration to be emitted from the one that ends the loop.

> (2) Functions such as tuple, list, set, dict*absorb*  StopIteration:
>
> py> list(iter([]))
> []
> py> it = iter([])
> py> list(next(it) for y in range(1000))
> []

Right, sometimes this doesn't happen.


> For-loops do the same, if StopIteration is raised in the "for x in
> iterable" header. That's how it knows the loop is done. The "for" part
> of a comprehension is the same.

I think this part is working as it should.

> (3) But raising StopIteration in the expression part (or if part) of a
> comprehension does not absord the exception, it is treated like any
> other exception:
>
> py> [next(iter([])) for y in range(1000)]
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
>    File "<stdin>", line 1, in <listcomp>
> StopIteration

This is not always working.  When a StopIteration is raised from the next 
call in the example that started the thread, it's getting replaced with the 
equivalent of a break, so it's never exiting the generator completely.  I 
think it needs to be replaced with the equivalent of return, which will end 
the generator, and cause a StopIteration to be emitted.  (As you describe 
here.)

It looks like it's a bug in the C code for generator expressions.  Since it 
only effects generator expressions that have iterators with nested loops, 
it may be fixible.

Cheers,
    Ron



More information about the Python-ideas mailing list