diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-10 06:53:51 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-10 06:53:51 (GMT) |
commit | 8f9cafad3d7f78193721d6c0ea84a499b36b7ce5 (patch) | |
tree | 16f80d4e907363db9bb5c934a34a768ed48cb58a /Modules | |
parent | 2d7250b3be5ce47e9246f8c6d4ce05dd7172e67c (diff) | |
parent | 8ddcf3abf7f899369801086bf39f60e0172a1470 (diff) | |
download | cpython-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.c | 45 |
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 */ |