Issue #19145: Fix handling of negative values for a "times" keyword argument to itertools.repeat()>

(Patch contributed by Vajrasky Kok.)
This commit is contained in:
Raymond Hettinger 2014-06-24 21:36:58 -07:00
parent ca5c7153de
commit 97d3555029
4 changed files with 23 additions and 2 deletions

View File

@ -967,6 +967,12 @@ class TestBasicOps(unittest.TestCase):
self.assertEqual(take(2, copy.deepcopy(c)), list('a' * 2)) self.assertEqual(take(2, copy.deepcopy(c)), list('a' * 2))
self.pickletest(repeat(object='a', times=10)) self.pickletest(repeat(object='a', times=10))
def test_repeat_with_negative_times(self):
self.assertEqual(repr(repeat('a', -1)), "repeat('a', 0)")
self.assertEqual(repr(repeat('a', -2)), "repeat('a', 0)")
self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)")
self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)")
def test_map(self): def test_map(self):
self.assertEqual(list(map(operator.pow, range(3), range(1,7))), self.assertEqual(list(map(operator.pow, range(3), range(1,7))),
[0**1, 1**2, 2**3]) [0**1, 1**2, 2**3])
@ -1741,8 +1747,15 @@ class LengthTransparency(unittest.TestCase):
def test_repeat(self): def test_repeat(self):
self.assertEqual(operator.length_hint(repeat(None, 50)), 50) self.assertEqual(operator.length_hint(repeat(None, 50)), 50)
self.assertEqual(operator.length_hint(repeat(None, 0)), 0)
self.assertEqual(operator.length_hint(repeat(None), 12), 12) self.assertEqual(operator.length_hint(repeat(None), 12), 12)
def test_repeat_with_negative_times(self):
self.assertEqual(operator.length_hint(repeat(None, -1)), 0)
self.assertEqual(operator.length_hint(repeat(None, -2)), 0)
self.assertEqual(operator.length_hint(repeat(None, times=-1)), 0)
self.assertEqual(operator.length_hint(repeat(None, times=-2)), 0)
class RegressionTests(unittest.TestCase): class RegressionTests(unittest.TestCase):
def test_sf_793826(self): def test_sf_793826(self):

View File

@ -1388,6 +1388,7 @@ Norman Vine
Pauli Virtanen Pauli Virtanen
Frank Visser Frank Visser
Johannes Vogel Johannes Vogel
Vajrasky Kok
Alex Volkov Alex Volkov
Martijn Vries Martijn Vries
Sjoerd de Vries Sjoerd de Vries

View File

@ -31,6 +31,10 @@ Library
- Issue #21832: Require named tuple inputs to be exact strings. - Issue #21832: Require named tuple inputs to be exact strings.
- Issue #19145: The times argument for itertools.repeat now handles
negative values the same way for keyword arguments as it does for
positional arguments.
- Issue #21812: turtle.shapetransform did not tranform the turtle on the - Issue #21812: turtle.shapetransform did not tranform the turtle on the
first call. (Issue identified and fixed by Lita Cho.) first call. (Issue identified and fixed by Lita Cho.)

View File

@ -4109,14 +4109,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
repeatobject *ro; repeatobject *ro;
PyObject *element; PyObject *element;
Py_ssize_t cnt = -1; Py_ssize_t cnt = -1, n_kwds = 0;
static char *kwargs[] = {"object", "times", NULL}; static char *kwargs[] = {"object", "times", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs, if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:repeat", kwargs,
&element, &cnt)) &element, &cnt))
return NULL; return NULL;
if (PyTuple_Size(args) == 2 && cnt < 0) if (kwds != NULL)
n_kwds = PyDict_Size(kwds);
/* Does user supply times argument? */
if ((PyTuple_Size(args) + n_kwds == 2) && cnt < 0)
cnt = 0; cnt = 0;
ro = (repeatobject *)type->tp_alloc(type, 0); ro = (repeatobject *)type->tp_alloc(type, 0);