implement `PySliceMethods`
This commit is contained in:
parent
f86053e2c2
commit
7918815cee
|
@ -1,6 +1,8 @@
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::ffi::{self, Py_ssize_t};
|
use crate::ffi::{self, Py_ssize_t};
|
||||||
use crate::{PyAny, PyObject, Python, ToPyObject};
|
use crate::ffi_ptr_ext::FfiPtrExt;
|
||||||
|
use crate::types::any::PyAnyMethods;
|
||||||
|
use crate::{Bound, PyAny, PyNativeType, PyObject, Python, ToPyObject};
|
||||||
use std::os::raw::c_long;
|
use std::os::raw::c_long;
|
||||||
|
|
||||||
/// Represents a Python `slice`.
|
/// Represents a Python `slice`.
|
||||||
|
@ -42,23 +44,52 @@ impl PySliceIndices {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PySlice {
|
impl PySlice {
|
||||||
/// Constructs a new slice with the given elements.
|
/// Deprecated form of `PySlice::new_bound`.
|
||||||
|
#[cfg_attr(
|
||||||
|
not(feature = "gil-refs"),
|
||||||
|
deprecated(
|
||||||
|
since = "0.21.0",
|
||||||
|
note = "`PySlice::new` will be replaced by `PySlice::new_bound` in a future PyO3 version"
|
||||||
|
)
|
||||||
|
)]
|
||||||
pub fn new(py: Python<'_>, start: isize, stop: isize, step: isize) -> &PySlice {
|
pub fn new(py: Python<'_>, start: isize, stop: isize, step: isize) -> &PySlice {
|
||||||
|
Self::new_bound(py, start, stop, step).into_gil_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructs a new slice with the given elements.
|
||||||
|
pub fn new_bound(py: Python<'_>, start: isize, stop: isize, step: isize) -> Bound<'_, PySlice> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ffi::PySlice_New(
|
ffi::PySlice_New(
|
||||||
ffi::PyLong_FromSsize_t(start),
|
ffi::PyLong_FromSsize_t(start),
|
||||||
ffi::PyLong_FromSsize_t(stop),
|
ffi::PyLong_FromSsize_t(stop),
|
||||||
ffi::PyLong_FromSsize_t(step),
|
ffi::PyLong_FromSsize_t(step),
|
||||||
);
|
)
|
||||||
|
.assume_owned(py)
|
||||||
|
.downcast_into_unchecked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated form of `PySlice::full_bound`.
|
||||||
|
#[cfg_attr(
|
||||||
|
not(feature = "gil-refs"),
|
||||||
|
deprecated(
|
||||||
|
since = "0.21.0",
|
||||||
|
note = "`PySlice::full` will be replaced by `PySlice::full_bound` in a future PyO3 version"
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
pub fn full(py: Python<'_>) -> &PySlice {
|
||||||
|
unsafe {
|
||||||
|
let ptr = ffi::PySlice_New(ffi::Py_None(), ffi::Py_None(), ffi::Py_None());
|
||||||
py.from_owned_ptr(ptr)
|
py.from_owned_ptr(ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new full slice that is equivalent to `::`.
|
/// Constructs a new full slice that is equivalent to `::`.
|
||||||
pub fn full(py: Python<'_>) -> &PySlice {
|
pub fn full_bound(py: Python<'_>) -> Bound<'_, PySlice> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ffi::PySlice_New(ffi::Py_None(), ffi::Py_None(), ffi::Py_None());
|
ffi::PySlice_New(ffi::Py_None(), ffi::Py_None(), ffi::Py_None())
|
||||||
py.from_owned_ptr(ptr)
|
.assume_owned(py)
|
||||||
|
.downcast_into_unchecked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +98,25 @@ impl PySlice {
|
||||||
/// slice in its `slicelength` member.
|
/// slice in its `slicelength` member.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn indices(&self, length: c_long) -> PyResult<PySliceIndices> {
|
pub fn indices(&self, length: c_long) -> PyResult<PySliceIndices> {
|
||||||
|
self.as_borrowed().indices(length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implementation of functionality for [`PySlice`].
|
||||||
|
///
|
||||||
|
/// These methods are defined for the `Bound<'py, PyTuple>` smart pointer, so to use method call
|
||||||
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
|
/// `arbitrary_self_types`.
|
||||||
|
#[doc(alias = "PySlice")]
|
||||||
|
pub trait PySliceMethods<'py> {
|
||||||
|
/// Retrieves the start, stop, and step indices from the slice object,
|
||||||
|
/// assuming a sequence of length `length`, and stores the length of the
|
||||||
|
/// slice in its `slicelength` member.
|
||||||
|
fn indices(&self, length: c_long) -> PyResult<PySliceIndices>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'py> PySliceMethods<'py> for Bound<'py, PySlice> {
|
||||||
|
fn indices(&self, length: c_long) -> PyResult<PySliceIndices> {
|
||||||
// non-negative Py_ssize_t should always fit into Rust usize
|
// non-negative Py_ssize_t should always fit into Rust usize
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut slicelength: isize = 0;
|
let mut slicelength: isize = 0;
|
||||||
|
@ -97,7 +147,7 @@ impl PySlice {
|
||||||
|
|
||||||
impl ToPyObject for PySliceIndices {
|
impl ToPyObject for PySliceIndices {
|
||||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||||
PySlice::new(py, self.start, self.stop, self.step).into()
|
PySlice::new_bound(py, self.start, self.stop, self.step).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +158,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_py_slice_new() {
|
fn test_py_slice_new() {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
let slice = PySlice::new(py, isize::MIN, isize::MAX, 1);
|
let slice = PySlice::new_bound(py, isize::MIN, isize::MAX, 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slice.getattr("start").unwrap().extract::<isize>().unwrap(),
|
slice.getattr("start").unwrap().extract::<isize>().unwrap(),
|
||||||
isize::MIN
|
isize::MIN
|
||||||
|
@ -127,7 +177,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_py_slice_full() {
|
fn test_py_slice_full() {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
let slice = PySlice::full(py);
|
let slice = PySlice::full_bound(py);
|
||||||
assert!(slice.getattr("start").unwrap().is_none(),);
|
assert!(slice.getattr("start").unwrap().is_none(),);
|
||||||
assert!(slice.getattr("stop").unwrap().is_none(),);
|
assert!(slice.getattr("stop").unwrap().is_none(),);
|
||||||
assert!(slice.getattr("step").unwrap().is_none(),);
|
assert!(slice.getattr("step").unwrap().is_none(),);
|
||||||
|
|
Loading…
Reference in New Issue