Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with
a macro if Py_LIMITED_API is not set or set to the value between 0x03050400 and 0x03060000 (not including) or 0x03060100 or higher. Added functions PySlice_Unpack() and PySlice_AdjustIndices().
This commit is contained in:
commit
6e08baf12d
|
@ -56,3 +56,40 @@ Slice Objects
|
||||||
.. versionchanged:: 3.2
|
.. versionchanged:: 3.2
|
||||||
The parameter type for the *slice* parameter was ``PySliceObject*``
|
The parameter type for the *slice* parameter was ``PySliceObject*``
|
||||||
before.
|
before.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6.1
|
||||||
|
If ``Py_LIMITED_API`` is not set or set to the value between ``0x03050400``
|
||||||
|
and ``0x03060000`` (not including) or ``0x03060100`` or higher
|
||||||
|
:c:func:`!PySlice_GetIndicesEx` is implemented as a macro using
|
||||||
|
:c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`.
|
||||||
|
Arguments *start*, *stop* and *step* are evaluated more than once.
|
||||||
|
|
||||||
|
.. deprecated:: 3.6.1
|
||||||
|
If ``Py_LIMITED_API`` is set to the value less than ``0x03050400`` or
|
||||||
|
between ``0x03060000`` and ``0x03060100`` (not including)
|
||||||
|
:c:func:`!PySlice_GetIndicesEx` is a deprecated function.
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: int PySlice_Unpack(PyObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
|
||||||
|
|
||||||
|
Extract the start, stop and step data members from a slice object as
|
||||||
|
C integers. Silently reduce values larger than ``PY_SSIZE_T_MAX`` to
|
||||||
|
``PY_SSIZE_T_MAX``, silently boost the start and stop values less than
|
||||||
|
``-PY_SSIZE_T_MAX-1`` to ``-PY_SSIZE_T_MAX-1``, and silently boost the step
|
||||||
|
values less than ``-PY_SSIZE_T_MAX`` to ``-PY_SSIZE_T_MAX``.
|
||||||
|
|
||||||
|
Return ``-1`` on error, ``0`` on success.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6.1
|
||||||
|
|
||||||
|
|
||||||
|
.. c:function:: Py_ssize_t PySlice_AdjustIndices(Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t step)
|
||||||
|
|
||||||
|
Adjust start/end slice indices assuming a sequence of the specified length.
|
||||||
|
Out of bounds indices are clipped in a manner consistent with the handling
|
||||||
|
of normal slices.
|
||||||
|
|
||||||
|
Return the length of the slice. Always successful. Doesn't call Python
|
||||||
|
code.
|
||||||
|
|
||||||
|
.. versionadded:: 3.6.1
|
||||||
|
|
|
@ -128,10 +128,17 @@ Build and C API Changes
|
||||||
is now of type ``const char *`` rather of ``char *``.
|
is now of type ``const char *`` rather of ``char *``.
|
||||||
(Contributed by Serhiy Storchaka in :issue:`28769`.)
|
(Contributed by Serhiy Storchaka in :issue:`28769`.)
|
||||||
|
|
||||||
|
* Added functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`.
|
||||||
|
(Contributed by Serhiy Storchaka in :issue:`27867`.)
|
||||||
|
|
||||||
|
|
||||||
Deprecated
|
Deprecated
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
- Function :c:func:`PySlice_GetIndicesEx` is deprecated and replaced with
|
||||||
|
a macro if ``Py_LIMITED_API`` is not set or set to the value between
|
||||||
|
``0x03050400`` and ``0x03060000`` (not including) or ``0x03060100`` or
|
||||||
|
higher. (Contributed by Serhiy Storchaka in :issue:`27867`.)
|
||||||
|
|
||||||
|
|
||||||
Removed
|
Removed
|
||||||
|
|
|
@ -41,8 +41,20 @@ PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length,
|
||||||
PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length,
|
PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length,
|
||||||
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step);
|
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step);
|
||||||
PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length,
|
PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length,
|
||||||
Py_ssize_t *start, Py_ssize_t *stop,
|
Py_ssize_t *start, Py_ssize_t *stop,
|
||||||
Py_ssize_t *step, Py_ssize_t *slicelength);
|
Py_ssize_t *step, Py_ssize_t *slicelength) Py_DEPRECATED(3.7);
|
||||||
|
|
||||||
|
#if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100
|
||||||
|
#define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \
|
||||||
|
PySlice_Unpack((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);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,6 +623,11 @@ Windows
|
||||||
C API
|
C API
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #27867: Function PySlice_GetIndicesEx() is deprecated and replaced with
|
||||||
|
a macro if Py_LIMITED_API is not set or set to the value between 0x03050400
|
||||||
|
and 0x03060000 (not including) or 0x03060100 or higher. Added functions
|
||||||
|
PySlice_Unpack() and PySlice_AdjustIndices().
|
||||||
|
|
||||||
- Issue #29083: Fixed the declaration of some public API functions.
|
- Issue #29083: Fixed the declaration of some public API functions.
|
||||||
PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in
|
PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in
|
||||||
limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and
|
limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and
|
||||||
|
|
|
@ -191,15 +191,12 @@ PySlice_GetIndices(PyObject *_r, Py_ssize_t length,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length,
|
PySlice_Unpack(PyObject *_r,
|
||||||
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
|
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
|
||||||
Py_ssize_t *slicelength)
|
|
||||||
{
|
{
|
||||||
PySliceObject *r = (PySliceObject*)_r;
|
PySliceObject *r = (PySliceObject*)_r;
|
||||||
/* this is harder to get right than you might think */
|
/* this is harder to get right than you might think */
|
||||||
|
|
||||||
Py_ssize_t defstart, defstop;
|
|
||||||
|
|
||||||
if (r->step == Py_None) {
|
if (r->step == Py_None) {
|
||||||
*step = 1;
|
*step = 1;
|
||||||
}
|
}
|
||||||
|
@ -219,42 +216,75 @@ PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length,
|
||||||
*step = -PY_SSIZE_T_MAX;
|
*step = -PY_SSIZE_T_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
defstart = *step < 0 ? length-1 : 0;
|
|
||||||
defstop = *step < 0 ? -1 : length;
|
|
||||||
|
|
||||||
if (r->start == Py_None) {
|
if (r->start == Py_None) {
|
||||||
*start = defstart;
|
*start = *step < 0 ? PY_SSIZE_T_MAX-1 : 0;;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!_PyEval_SliceIndex(r->start, start)) return -1;
|
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) {
|
if (r->stop == Py_None) {
|
||||||
*stop = defstop;
|
*stop = *step < 0 ? -PY_SSIZE_T_MAX : PY_SSIZE_T_MAX;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
|
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)
|
return 0;
|
||||||
|| (*step > 0 && *start >= *stop)) {
|
}
|
||||||
*slicelength = 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) {
|
else if (*start >= length) {
|
||||||
*slicelength = (*stop-*start+1)/(*step)+1;
|
*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 {
|
else {
|
||||||
*slicelength = (*stop-*start-1)/(*step)+1;
|
if (*start < *stop) {
|
||||||
|
return (*stop - *start - 1) / step + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef PySlice_GetIndicesEx
|
||||||
|
|
||||||
|
int
|
||||||
|
PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length,
|
||||||
|
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
|
||||||
|
Py_ssize_t *slicelength)
|
||||||
|
{
|
||||||
|
if (PySlice_Unpack(_r, start, stop, step) < 0)
|
||||||
|
return -1;
|
||||||
|
*slicelength = PySlice_AdjustIndices(length, start, stop, *step);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -531,10 +531,12 @@ EXPORTS
|
||||||
PySet_Pop=python37.PySet_Pop
|
PySet_Pop=python37.PySet_Pop
|
||||||
PySet_Size=python37.PySet_Size
|
PySet_Size=python37.PySet_Size
|
||||||
PySet_Type=python37.PySet_Type DATA
|
PySet_Type=python37.PySet_Type DATA
|
||||||
|
PySlice_AdjustIndices=python37.PySlice_AdjustIndices
|
||||||
PySlice_GetIndices=python37.PySlice_GetIndices
|
PySlice_GetIndices=python37.PySlice_GetIndices
|
||||||
PySlice_GetIndicesEx=python37.PySlice_GetIndicesEx
|
PySlice_GetIndicesEx=python37.PySlice_GetIndicesEx
|
||||||
PySlice_New=python37.PySlice_New
|
PySlice_New=python37.PySlice_New
|
||||||
PySlice_Type=python37.PySlice_Type DATA
|
PySlice_Type=python37.PySlice_Type DATA
|
||||||
|
PySlice_Unpack=python37.PySlice_Unpack
|
||||||
PySortWrapper_Type=python37.PySortWrapper_Type DATA
|
PySortWrapper_Type=python37.PySortWrapper_Type DATA
|
||||||
PyState_AddModule=python37.PyState_AddModule
|
PyState_AddModule=python37.PyState_AddModule
|
||||||
PyState_FindModule=python37.PyState_FindModule
|
PyState_FindModule=python37.PyState_FindModule
|
||||||
|
|
Loading…
Reference in New Issue