[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