From 8afc8c6fda8b7930ca0691f79baecc8320e50ea9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 24 Sep 2026 15:53:10 +0200 Subject: [PATCH] gh-158077: Remove deprecated PySlice_GetIndicesEx() function Only remove the function implementation. PySlice_GetIndicesEx() remains available as a static inline function, so the API does not change. Convert PySlice_GetIndicesEx() macro to a static inline functions. Arguments are now only evaluated once. The function is no longer supported on limited C API older than 3.6.1. --- Doc/c-api/slice.rst | 11 +++---- Doc/data/stable_abi.dat | 1 - .../c-api-pending-removal-in-future.rst | 2 -- Doc/whatsnew/3.16.rst | 5 ++++ Include/sliceobject.h | 29 +++++++++++-------- ...-09-24-16-05-50.gh-issue-158077.DEaM49.rst | 4 +++ Misc/stable_abi.toml | 1 + Objects/sliceobject.c | 8 +++-- 8 files changed, 39 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/C_API/2026-09-24-16-05-50.gh-issue-158077.DEaM49.rst diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index c6d761fe7fd1c96..575bc8e7da26956 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -68,9 +68,11 @@ Slice Objects is replaced by :: if (PySlice_Unpack(slice, &start, &stop, &step) < 0) { - // return error + slicelength = 0; + return -1; } slicelength = PySlice_AdjustIndices(length, &start, &stop, step); + return 0; .. versionchanged:: 3.2 The parameter type for the *slice* parameter was ``PySliceObject*`` @@ -83,10 +85,9 @@ Slice Objects :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. + .. versionchanged:: next + :c:func:`!PySlice_GetIndicesEx` is now implemented as a static inline + function. Arguments are only evaluated once. .. c:function:: int PySlice_Unpack(PyObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step) diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 662158323c5d305..ffc3042566b33f8 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -679,7 +679,6 @@ func,PySet_Size,3.2,, data,PySet_Type,3.2,, func,PySlice_AdjustIndices,3.7,, func,PySlice_GetIndices,3.2,, -func,PySlice_GetIndicesEx,3.2,, func,PySlice_New,3.2,, data,PySlice_Type,3.2,, func,PySlice_Unpack,3.7,, diff --git a/Doc/deprecations/c-api-pending-removal-in-future.rst b/Doc/deprecations/c-api-pending-removal-in-future.rst index 841d1b455b6bec6..55dc4083ed43ec4 100644 --- a/Doc/deprecations/c-api-pending-removal-in-future.rst +++ b/Doc/deprecations/c-api-pending-removal-in-future.rst @@ -16,8 +16,6 @@ although there is currently no date scheduled for their removal. Use :c:func:`PyModule_GetFilenameObject` instead. * :c:func:`PyOS_AfterFork`: Use :c:func:`PyOS_AfterFork_Child` instead. -* :c:func:`PySlice_GetIndicesEx`: - Use :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` instead. * :c:func:`PyUnicode_READY`: Unneeded since Python 3.12 * :c:func:`!PyErr_Display`: diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index c76681261f6746d..b6d5cda8a4ff468 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -1128,6 +1128,11 @@ Deprecated C APIs and :c:func:`PyAsyncGen_New` are deprecated. They are scheduled for removal in 3.18. +* Remove :c:func:`PySlice_GetIndicesEx` function, deprecated since Python 3.7. + Only remove the function implementation: :c:func:`PySlice_GetIndicesEx` + remains available as a static inline function, so the API does not change. + (Contributed by Victor Stinner in :gh:`158077`.) + .. Add C API deprecations above alphabetically, not here at the end. .. include:: ../deprecations/c-api-pending-removal-in-3.18.rst diff --git a/Include/sliceobject.h b/Include/sliceobject.h index 9d6a16da95fe2f5..76b5b4b268fbef1 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -25,23 +25,28 @@ PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); -Py_DEPRECATED(3.7) -PyAPI_FUNC(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 !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 ? \ - ((*(slicelen) = 0), -1) : \ - ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ - 0)) + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060100 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); + +static inline int +_PySlice_GetIndicesEx(PyObject *slice, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, + Py_ssize_t *slicelen) +{ + if (PySlice_Unpack(slice, start, stop, step) < 0) { + *slicelen = 0; + return -1; + } + + *slicelen = PySlice_AdjustIndices(length, start, stop, *step); + return 0; +} +#define PySlice_GetIndicesEx _PySlice_GetIndicesEx #endif #ifndef Py_LIMITED_API diff --git a/Misc/NEWS.d/next/C_API/2026-09-24-16-05-50.gh-issue-158077.DEaM49.rst b/Misc/NEWS.d/next/C_API/2026-09-24-16-05-50.gh-issue-158077.DEaM49.rst new file mode 100644 index 000000000000000..f777906096e0997 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-09-24-16-05-50.gh-issue-158077.DEaM49.rst @@ -0,0 +1,4 @@ +Remove :c:func:`PySlice_GetIndicesEx` function, deprecated since Python 3.7. +Only remove the function implementation: :c:func:`PySlice_GetIndicesEx` +remains available as a static inline function, so the API does not change. +Patch by Victor Stinner. diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index 08fd7009dbc4b86..fad5b7a8d0d4168 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -1314,6 +1314,7 @@ added = '3.2' [function.PySlice_GetIndicesEx] added = '3.2' + abi_only = true [function.PySlice_New] added = '3.2' [data.PySlice_Type] diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 91d1753b822fc13..8e956394d3a0617 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -297,13 +297,17 @@ PySlice_AdjustIndices(Py_ssize_t length, #undef PySlice_GetIndicesEx -int +// Function removed from Python 3.16 C API, but kept in the stable ABI +PyAPI_FUNC(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) + if (PySlice_Unpack(_r, start, stop, step) < 0) { + *slicelength = 0; return -1; + } + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); return 0; }