summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-09-10 06:53:51 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-09-10 06:53:51 (GMT)
commit8f9cafad3d7f78193721d6c0ea84a499b36b7ce5 (patch)
tree16f80d4e907363db9bb5c934a34a768ed48cb58a /Modules
parent2d7250b3be5ce47e9246f8c6d4ce05dd7172e67c (diff)
parent8ddcf3abf7f899369801086bf39f60e0172a1470 (diff)
downloadcpython-8f9cafad3d7f78193721d6c0ea84a499b36b7ce5.zip
cpython-8f9cafad3d7f78193721d6c0ea84a499b36b7ce5.tar.gz
cpython-8f9cafad3d7f78193721d6c0ea84a499b36b7ce5.tar.bz2
Issue #28019: itertools.count() no longer rounds non-integer step in range
between 1.0 and 2.0 to 1.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/itertoolsmodule.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index c966376..62b6a0c 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -3907,7 +3907,7 @@ static PyObject *
count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
countobject *lz;
- int slow_mode = 0;
+ int fast_mode;
Py_ssize_t cnt = 0;
PyObject *long_cnt = NULL;
PyObject *long_step = NULL;
@@ -3924,16 +3924,26 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
+ fast_mode = (long_cnt == NULL || PyLong_Check(long_cnt)) &&
+ (long_step == NULL || PyLong_Check(long_step));
+
+ /* If not specified, start defaults to 0 */
if (long_cnt != NULL) {
- cnt = PyLong_AsSsize_t(long_cnt);
- if ((cnt == -1 && PyErr_Occurred()) || !PyLong_Check(long_cnt)) {
- PyErr_Clear();
- slow_mode = 1;
+ if (fast_mode) {
+ assert(PyLong_Check(long_cnt));
+ cnt = PyLong_AsSsize_t(long_cnt);
+ if (cnt == -1 && PyErr_Occurred()) {
+ PyErr_Clear();
+ fast_mode = 0;
+ }
}
Py_INCREF(long_cnt);
} else {
cnt = 0;
long_cnt = PyLong_FromLong(0);
+ if (long_cnt == NULL) {
+ return NULL;
+ }
}
/* If not specified, step defaults to 1 */
@@ -3949,21 +3959,24 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
assert(long_cnt != NULL && long_step != NULL);
/* Fast mode only works when the step is 1 */
- step = PyLong_AsLong(long_step);
- if (step != 1) {
- slow_mode = 1;
- if (step == -1 && PyErr_Occurred())
- PyErr_Clear();
+ if (fast_mode) {
+ assert(PyLong_Check(long_step));
+ step = PyLong_AsLong(long_step);
+ if (step != 1) {
+ fast_mode = 0;
+ if (step == -1 && PyErr_Occurred())
+ PyErr_Clear();
+ }
}
- if (slow_mode)
- cnt = PY_SSIZE_T_MAX;
- else
+ if (fast_mode)
Py_CLEAR(long_cnt);
+ else
+ cnt = PY_SSIZE_T_MAX;
- assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && !slow_mode) ||
- (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && slow_mode));
- assert(slow_mode ||
+ assert((cnt != PY_SSIZE_T_MAX && long_cnt == NULL && fast_mode) ||
+ (cnt == PY_SSIZE_T_MAX && long_cnt != NULL && !fast_mode));
+ assert(!fast_mode ||
(PyLong_Check(long_step) && PyLong_AS_LONG(long_step) == 1));
/* create countobject structure */