diff --git a/src/ffi/sliceobject.rs b/src/ffi/sliceobject.rs index b8a557ce..fa73102d 100644 --- a/src/ffi/sliceobject.rs +++ b/src/ffi/sliceobject.rs @@ -12,6 +12,15 @@ pub unsafe fn Py_Ellipsis() -> *mut PyObject { &mut _Py_EllipsisObject } +#[cfg(not(Py_LIMITED_API))] +#[repr(C)] +pub struct PySliceObject { + pub ob_base: PyObject, + pub start: *mut PyObject, + pub stop: *mut PyObject, + pub step: *mut PyObject, +} + #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { #[cfg_attr(PyPy, link_name = "PyPySlice_Type")] @@ -24,14 +33,6 @@ pub unsafe fn PySlice_Check(op: *mut PyObject) -> c_int { (Py_TYPE(op) == &mut PySlice_Type) as c_int } -#[repr(C)] -pub struct PySliceObject { - pub ob_base: PyObject, - pub start: *mut PyObject, - pub stop: *mut PyObject, - pub step: *mut PyObject, -} - extern "C" { #[cfg_attr(PyPy, link_name = "PyPySlice_New")] pub fn PySlice_New( @@ -39,6 +40,10 @@ extern "C" { stop: *mut PyObject, step: *mut PyObject, ) -> *mut PyObject; + + // skipped non-limited _PySlice_FromIndices + // skipped non-limited _PySlice_GetLongIndices + #[cfg_attr(PyPy, link_name = "PyPySlice_GetIndices")] pub fn PySlice_GetIndices( r: *mut PyObject, @@ -47,6 +52,8 @@ extern "C" { stop: *mut Py_ssize_t, step: *mut Py_ssize_t, ) -> c_int; + + #[cfg(not(Py_3_7))] #[cfg_attr(PyPy, link_name = "PyPySlice_GetIndicesEx")] pub fn PySlice_GetIndicesEx( r: *mut PyObject, @@ -57,3 +64,39 @@ extern "C" { slicelength: *mut Py_ssize_t, ) -> c_int; } + +#[cfg(Py_3_7)] +#[inline] +pub unsafe fn PySlice_GetIndicesEx( + slice: *mut PyObject, + length: Py_ssize_t, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: *mut Py_ssize_t, + slicelength: *mut Py_ssize_t, +) -> c_int { + if PySlice_Unpack(slice, start, stop, step) < 0 { + *slicelength = 0; + -1 + } else { + *slicelength = PySlice_AdjustIndices(length, start, stop, *step); + 0 + } +} + +extern "C" { + #[cfg_attr(PyPy, link_name = "PyPySlice_Unpack")] + pub fn PySlice_Unpack( + slice: *mut PyObject, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: *mut Py_ssize_t, + ) -> c_int; + + pub fn PySlice_AdjustIndices( + length: Py_ssize_t, + start: *mut Py_ssize_t, + stop: *mut Py_ssize_t, + step: Py_ssize_t, + ) -> Py_ssize_t; +}