FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Issue #28019: itertools.count() no longer rounds non-integer step in … · python/cpython@8ddcf3a · GitHub

Repository navigation

Commit 8ddcf3a

Browse files
Issue #28019: itertools.count() no longer rounds non-integer step in range
between 1.0 and 2.0 to 1.
1 parent e617521 commit 8ddcf3a

3 files changed

Lines changed: 55 additions & 21 deletions

File tree

‎Lib/test/test_itertools.py‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -511,21 +511,29 @@ def test_count(self):
511511
self.assertEqual(take(2, zip('abc',count(-3))), [('a', -3), ('b', -2)])
512512
self.assertRaises(TypeError, count, 2, 3, 4)
513513
self.assertRaises(TypeError, count, 'a')
514-
self.assertEqual(list(islice(count(maxsize-5), 10)),
514+
self.assertEqual(take(10, count(maxsize-5)),
515515
list(range(maxsize-5, maxsize+5)))
516-
self.assertEqual(list(islice(count(-maxsize-5), 10)),
516+
self.assertEqual(take(10, count(-maxsize-5)),
517517
list(range(-maxsize-5, -maxsize+5)))
518-
self.assertEqual(list(islice(count(10, maxsize+5), 3)),
519-
list(range(10, 10+3*(maxsize+5), maxsize+5)))
518+
self.assertEqual(take(3, count(3.25)), [3.25, 4.25, 5.25])
519+
self.assertEqual(take(3, count(3.25-4j)), [3.25-4j, 4.25-4j, 5.25-4j])
520+
self.assertEqual(take(3, count(Decimal('1.1'))),
521+
[Decimal('1.1'), Decimal('2.1'), Decimal('3.1')])
522+
self.assertEqual(take(3, count(Fraction(2, 3))),
523+
[Fraction(2, 3), Fraction(5, 3), Fraction(8, 3)])
524+
BIGINT = 1<<1000
525+
self.assertEqual(take(3, count(BIGINT)), [BIGINT, BIGINT+1, BIGINT+2])
520526
c = count(3)
521527
self.assertEqual(repr(c), 'count(3)')
522528
next(c)
523529
self.assertEqual(repr(c), 'count(4)')
524530
c = count(-9)
525531
self.assertEqual(repr(c), 'count(-9)')
526532
next(c)
527-
self.assertEqual(repr(count(10.25)), 'count(10.25)')
528533
self.assertEqual(next(c), -8)
534+
self.assertEqual(repr(count(10.25)), 'count(10.25)')
535+
self.assertEqual(repr(count(10.0)), 'count(10.0)')
536+
self.assertEqual(type(next(count(10.0))), float)
529537
for i in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 10, sys.maxsize-5, sys.maxsize+5):
530538
# Test repr
531539
r1 = repr(count(i))
@@ -549,16 +557,22 @@ def test_count_with_stride(self):
549557
[('a', 2), ('b', 5), ('c', 8)])
550558
self.assertEqual(lzip('abc',count(step=-1)),
551559
[('a', 0), ('b', -1), ('c', -2)])
560+
self.assertRaises(TypeError, count, 'a', 'b')
552561
self.assertEqual(lzip('abc',count(2,0)), [('a', 2), ('b', 2), ('c', 2)])
553562
self.assertEqual(lzip('abc',count(2,1)), [('a', 2), ('b', 3), ('c', 4)])
554563
self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)])
555564
self.assertEqual(take(20, count(maxsize-15, 3)), take(20, range(maxsize-15, maxsize+100, 3)))
556565
self.assertEqual(take(20, count(-maxsize-15, 3)), take(20, range(-maxsize-15,-maxsize+100, 3)))
566+
self.assertEqual(take(3, count(10, maxsize+5)),
567+
list(range(10, 10+3*(maxsize+5), maxsize+5)))
568+
self.assertEqual(take(3, count(2, 1.25)), [2, 3.25, 4.5])
557569
self.assertEqual(take(3, count(2, 3.25-4j)), [2, 5.25-4j, 8.5-8j])
558570
self.assertEqual(take(3, count(Decimal('1.1'), Decimal('.1'))),
559571
[Decimal('1.1'), Decimal('1.2'), Decimal('1.3')])
560572
self.assertEqual(take(3, count(Fraction(2,3), Fraction(1,7))),
561573
[Fraction(2,3), Fraction(17,21), Fraction(20,21)])
574+
BIGINT = 1<<1000
575+
self.assertEqual(take(3, count(step=BIGINT)), [0, BIGINT, 2*BIGINT])
562576
self.assertEqual(repr(take(3, count(10, 2.5))), repr([10, 12.5, 15.0]))
563577
c = count(3, 5)
564578
self.assertEqual(repr(c), 'count(3, 5)')
@@ -576,6 +590,10 @@ def test_count_with_stride(self):
576590
self.assertEqual(repr(count(10.5, 1.25)), 'count(10.5, 1.25)')
577591
self.assertEqual(repr(count(10.5, 1)), 'count(10.5)') # suppress step=1 when it's an int
578592
self.assertEqual(repr(count(10.5, 1.00)), 'count(10.5, 1.0)') # do show float values lilke 1.0
593+
self.assertEqual(repr(count(10, 1.00)), 'count(10, 1.0)')
594+
c = count(10, 1.0)
595+
self.assertEqual(type(next(c)), int)
596+
self.assertEqual(type(next(c)), float)
579597
for i in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 10, sys.maxsize-5, sys.maxsize+5):
580598
for j in (-sys.maxsize-5, -sys.maxsize+5 ,-10, -1, 0, 1, 10, sys.maxsize-5, sys.maxsize+5):
581599
# Test repr

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ Core and Builtins
6565
Library
6666
-------
6767

68+
- Issue #28019: itertools.count() no longer rounds non-integer step in range
69+
between 1.0 and 2.0 to 1.
70+
6871
- Issue #25969: Update the lib2to3 grammar to handle the unpacking
6972
generalizations added in 3.5.
7073

‎Modules/itertoolsmodule.c‎

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3905,7 +3905,7 @@ static PyObject *
39053905
count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
39063906
{
39073907
countobject *lz;
3908-
int slow_mode = 0;
3908+
int fast_mode;
39093909
Py_ssize_t cnt = 0;
39103910
PyObject *long_cnt = NULL;
39113911
PyObject *long_step = NULL;
@@ -3922,16 +3922,26 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
39223922
return NULL;
39233923
}
39243924

3925+
fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) &&
3926+
(long_step == NULL || PyLong_Check(long_step));
3927+
3928+
/* If not specified, start defaults to 0 */
39253929
if (long_cnt != NULL) {
3926-
cnt = PyLong_AsSsize_t(long_cnt);
3927-
if ((cnt == -1 && PyErr_Occurred()) || !PyLong_Check(long_cnt)) {
3928-
PyErr_Clear();
3929-
slow_mode = 1;
3930+
if (fast_mode) {
3931+
assert(PyLong_Check(long_cnt));
3932+
cnt = PyLong_AsSsize_t(long_cnt);
3933+
if (cnt == -1 && PyErr_Occurred()) {
3934+
PyErr_Clear();
3935+
fast_mode = 0;
3936+
}
39303937
}
39313938
Py_INCREF(long_cnt);
39323939
} else {
39333940
cnt = 0;
39343941
long_cnt = PyLong_FromLong(0);
3942+
if (long_cnt == NULL) {
3943+
return NULL;
3944+
}
39353945
}
39363946

39373947
/* If not specified, step defaults to 1 */
@@ -3947,21 +3957,24 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
39473957
assert(long_cnt != NULL && long_step != NULL);
39483958

39493959
/* Fast mode only works when the step is 1 */
3950-
step = PyLong_AsLong(long_step);
3951-
if (step != 1) {
3952-
slow_mode = 1;
3953-
if (step == -1 && PyErr_Occurred())
3954-
PyErr_Clear();
3960+
if (fast_mode) {
3961+
assert(PyLong_Check(long_step));
3962+
step = PyLong_AsLong(long_step);
3963+
if (step != 1) {
3964+
fast_mode = 0;
3965+
if (step == -1 && PyErr_Occurred())
3966+
PyErr_Clear();
3967+
}
39553968
}
39563969

3957-
if (slow_mode)
3958-
cnt = PY_SSIZE_T_MAX;
3959-
else
3970+
if (fast_mode)
39603971
Py_CLEAR(long_cnt);
3972+
else
3973+
cnt = PY_SSIZE_T_MAX;
39613974

3962-
assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && !slow_mode) ||
3963-
(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && slow_mode));
3964-
assert(slow_mode ||
3975+
assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) ||
3976+
(cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode));
3977+
assert(!fast_mode ||
39653978
(PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1));
39663979

39673980
/* create countobject structure */

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL