cpython (2.7): Issue #27867: Replaced function PySlice_GetIndicesEx() with a macro.
https://hg.python.org/cpython/rev/d5590f357d74 changeset: 106311:d5590f357d74 branch: 2.7 parent: 106292:fb2885f9b4dd user: Serhiy Storchaka <storchaka@gmail.com> date: Wed Jan 25 13:22:06 2017 +0200 summary: Issue #27867: Replaced function PySlice_GetIndicesEx() with a macro. files: Include/sliceobject.h | 10 +++ Misc/NEWS | 5 + Objects/sliceobject.c | 78 +++++++++++++++++++++--------- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/Include/sliceobject.h b/Include/sliceobject.h --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -38,6 +38,16 @@ Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); +#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ + _PySlice_Unpack((PyObject *)(slice), (start), (stop), (step)) < 0 ? -1 : \ + ((*slicelen = _PySlice_AdjustIndices((length), (start), (stop), *(step))), \ + 0)) +PyAPI_FUNC(int) _PySlice_Unpack(PyObject *slice, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(Py_ssize_t) _PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t step); + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -68,6 +68,11 @@ - Issue #28925: cPickle now correctly propagates errors when unpickle instances of old-style classes. +C API +----- + +- Issue #27867: Function PySlice_GetIndicesEx() is replaced with a macro. + Build ----- diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -131,13 +131,12 @@ } int -PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) +_PySlice_Unpack(PyObject *_r, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) { + PySliceObject *r = (PySliceObject *)_r; /* this is harder to get right than you might think */ - Py_ssize_t defstart, defstop; - if (r->step == Py_None) { *step = 1; } @@ -150,42 +149,75 @@ } } - defstart = *step < 0 ? length-1 : 0; - defstop = *step < 0 ? -1 : length; - if (r->start == Py_None) { - *start = defstart; + *start = *step < 0 ? PY_SSIZE_T_MAX-1 : 0;; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; - if (*start < 0) *start += length; - if (*start < 0) *start = (*step < 0) ? -1 : 0; - if (*start >= length) - *start = (*step < 0) ? length - 1 : length; } if (r->stop == Py_None) { - *stop = defstop; + *stop = *step < 0 ? -PY_SSIZE_T_MAX : PY_SSIZE_T_MAX; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; - if (*stop < 0) *stop += length; - if (*stop < 0) *stop = (*step < 0) ? -1 : 0; - if (*stop >= length) - *stop = (*step < 0) ? length - 1 : length; } - if ((*step < 0 && *stop >= *start) - || (*step > 0 && *start >= *stop)) { - *slicelength = 0; + return 0; +} + +Py_ssize_t +_PySlice_AdjustIndices(Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t step) +{ + /* this is harder to get right than you might think */ + + assert(step != 0); + assert(step >= -PY_SSIZE_T_MAX); + + if (*start < 0) { + *start += length; + if (*start < 0) { + *start = (step < 0) ? -1 : 0; + } } - else if (*step < 0) { - *slicelength = (*stop-*start+1)/(*step)+1; + else if (*start >= length) { + *start = (step < 0) ? length - 1 : length; + } + + if (*stop < 0) { + *stop += length; + if (*stop < 0) { + *stop = (step < 0) ? -1 : 0; + } + } + else if (*stop >= length) { + *stop = (step < 0) ? length - 1 : length; + } + + if (step < 0) { + if (*stop < *start) { + return (*start - *stop - 1) / (-step) + 1; + } } else { - *slicelength = (*stop-*start-1)/(*step)+1; + if (*start < *stop) { + return (*stop - *start - 1) / step + 1; + } } + return 0; +} +#undef PySlice_GetIndicesEx + +int +PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelength) +{ + if (_PySlice_Unpack((PyObject *)r, start, stop, step) < 0) + return -1; + *slicelength = _PySlice_AdjustIndices(length, start, stop, *step); return 0; } -- Repository URL: https://hg.python.org/cpython
participants (1)
-
serhiy.storchaka