[Python-Dev] Negative times behaviour in itertools.repeat for Python maintenance releases (2.7, 3.3 and maybe 3.4)

Steven D'Aprano steve at pearwood.info
Mon Jan 27 07:31:34 CET 2014


On Sun, Jan 26, 2014 at 11:40:33PM -0500, Alexander Belopolsky wrote:

> I would say no fix is needed for this doc because the signature suggests
> (correctly) that passing times by keyword is not supported.

How do you determine that? Passing times by keyword works in Python 3.3:

py> from itertools import repeat
py> it = repeat("a", times=5)
py> list(it)
['a', 'a', 'a', 'a', 'a']


The docstring signature names both parameters:

py> print(repeat.__doc__)
repeat(object [,times]) -> create an iterator which returns the object
for the specified number of times.  If not specified, returns the object
endlessly.


And both names work fine:

py> repeat(object=2, times=5)
repeat(2, 5)


Judging from the docstring and current behaviour, I think we can 
conclude that:

- keyword arguments are fine;

- there shouldn't be any difference between providing a value
  by position or by keyword;

- repeat(x) should yield x forever;

- repeat(x, 0) should immediately raise StopIteration;

- repeat(x, -n) is not specified by the docstring, but the 
  documentation on the website makes it clear that it should 
  be equivalent to repeat(x, 0) no matter the magnitude of -n;

- which matches the behaviour of [x]*-n nicely.


As far as I'm concerned, this is a clear case of a bug. Providing 
times=None (by keyword or by position) ought to be equivalent to not 
providing times at all, and any negative times ought to be equivalent to 
zero.


> The following behavior further supports this interpretation.
> 
> >>> from itertools import *
> >>> ''.join(repeat('a', times=-4))
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> OverflowError: long int too large to convert to int

I don't think it does. I think it suggests that something is trying to 
convert an unsigned value into an int, and failing. I note that repeat 
is happy to work with negatives times one at a time:

py> it = repeat('a', times=-4)
py> next(it)
'a'


-- 
Steven


More information about the Python-Dev mailing list