[Python-3000] Is this a bug with list comprehensions or not?

Adam Olsen rhamph at gmail.com
Fri Jul 11 21:23:29 CEST 2008


On Thu, Jul 10, 2008 at 11:45 PM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> Greg Ewing wrote:
>> Antoine Pitrou wrote:
>>
>>> That is, in your example:
>>>
>>>  >>> def f(x):
>>> ...  if x > 5: raise StopIteration
>>> ...
>>>  >>> list(x for x in range(100) if not f(x))
>>> [0, 1, 2, 3, 4, 5]
>>>
>>> f() certainly shouldn't raise a StopIteration. There's no reason for
>>> doing
>>> that, other than taking dirty implementation shortcuts and ending up with
>>> difficult to maintain code.
>>
>> I'm inclined to agree. This code seems to be designed
>> to cause the LC to exit early, which IMO is an abuse
>> of LCs. If you need a loop that doesn't run to
>> completion, you should write it out as a for-loop.
>>
>> So no, this is not a bug, since in well-designed code
>> the difference in behaviour shouldn't matter.
>
> While I agree with this being bad design, I do think that the above is a bug.
> It's a different thing if the iterable in the list comp/genexp raises a
> StopIteration, or if the conditional does it. And not silently catching
> anything raised by the latter sounds like the right thing to me.

Since all exceptions from a genexp go up through .next(), you can't
distinguish a proper StopIteration from an improper StopIteration.
However, since the genexp considers all improper ones to be in error,
it could wrap them with a RuntimeError and pass it through .next()
instead.

Once genexps are fixed to do that then there's no reason not to make
listcomps match, which seems to be a goal here.


-- 
Adam Olsen, aka Rhamphoryncus


More information about the Python-3000 mailing list