seals `PyAnyMethods` and friends (#3909)
* seals `PyAnyMethods` and friends This seals these new traits, preventing downstream crates from implementing them on their types. These traits are mainly a workaround for arbitrary self receiver types, so this gives us more flexibility if these need to be changed in the future. * move `PyResultExt` seal
This commit is contained in:
parent
8a12970c96
commit
55833365b5
|
@ -1,19 +1,10 @@
|
||||||
|
use crate::sealed::Sealed;
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi,
|
ffi,
|
||||||
instance::{Borrowed, Bound},
|
instance::{Borrowed, Bound},
|
||||||
PyAny, PyResult, Python,
|
PyAny, PyResult, Python,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod sealed {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Sealed {}
|
|
||||||
|
|
||||||
impl Sealed for *mut ffi::PyObject {}
|
|
||||||
}
|
|
||||||
|
|
||||||
use sealed::Sealed;
|
|
||||||
|
|
||||||
pub(crate) trait FfiPtrExt: Sealed {
|
pub(crate) trait FfiPtrExt: Sealed {
|
||||||
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>>;
|
unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult<Bound<'_, PyAny>>;
|
||||||
unsafe fn assume_owned_or_opt(self, py: Python<'_>) -> Option<Bound<'_, PyAny>>;
|
unsafe fn assume_owned_or_opt(self, py: Python<'_>) -> Option<Bound<'_, PyAny>>;
|
||||||
|
|
|
@ -324,6 +324,7 @@ pub use crate::version::PythonVersionInfo;
|
||||||
|
|
||||||
pub(crate) mod ffi_ptr_ext;
|
pub(crate) mod ffi_ptr_ext;
|
||||||
pub(crate) mod py_result_ext;
|
pub(crate) mod py_result_ext;
|
||||||
|
pub(crate) mod sealed;
|
||||||
|
|
||||||
/// Old module which contained some implementation details of the `#[pyproto]` module.
|
/// Old module which contained some implementation details of the `#[pyproto]` module.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
use crate::{types::any::PyAnyMethods, Bound, PyAny, PyResult, PyTypeCheck};
|
use crate::{types::any::PyAnyMethods, Bound, PyAny, PyResult, PyTypeCheck};
|
||||||
|
|
||||||
mod sealed {
|
pub(crate) trait PyResultExt<'py>: crate::sealed::Sealed {
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub trait Sealed {}
|
|
||||||
|
|
||||||
impl Sealed for PyResult<Bound<'_, PyAny>> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
use sealed::Sealed;
|
|
||||||
|
|
||||||
pub(crate) trait PyResultExt<'py>: Sealed {
|
|
||||||
fn downcast_into<T: PyTypeCheck>(self) -> PyResult<Bound<'py, T>>;
|
fn downcast_into<T: PyTypeCheck>(self) -> PyResult<Bound<'py, T>>;
|
||||||
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Bound<'py, T>>;
|
unsafe fn downcast_into_unchecked<T>(self) -> PyResult<Bound<'py, T>>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
use crate::types::{
|
||||||
|
PyBool, PyByteArray, PyBytes, PyCapsule, PyComplex, PyDict, PyFloat, PyFrozenSet, PyList,
|
||||||
|
PyMapping, PyModule, PySequence, PySet, PySlice, PyString, PyTraceback, PyTuple, PyType,
|
||||||
|
};
|
||||||
|
use crate::{ffi, Bound, PyAny, PyResult};
|
||||||
|
|
||||||
|
pub trait Sealed {}
|
||||||
|
|
||||||
|
// for FfiPtrExt
|
||||||
|
impl Sealed for *mut ffi::PyObject {}
|
||||||
|
|
||||||
|
// for PyResultExt
|
||||||
|
impl Sealed for PyResult<Bound<'_, PyAny>> {}
|
||||||
|
|
||||||
|
// for Py(...)Methods
|
||||||
|
impl Sealed for Bound<'_, PyAny> {}
|
||||||
|
impl Sealed for Bound<'_, PyBool> {}
|
||||||
|
impl Sealed for Bound<'_, PyByteArray> {}
|
||||||
|
impl Sealed for Bound<'_, PyBytes> {}
|
||||||
|
impl Sealed for Bound<'_, PyCapsule> {}
|
||||||
|
impl Sealed for Bound<'_, PyComplex> {}
|
||||||
|
impl Sealed for Bound<'_, PyDict> {}
|
||||||
|
impl Sealed for Bound<'_, PyFloat> {}
|
||||||
|
impl Sealed for Bound<'_, PyFrozenSet> {}
|
||||||
|
impl Sealed for Bound<'_, PyList> {}
|
||||||
|
impl Sealed for Bound<'_, PyMapping> {}
|
||||||
|
impl Sealed for Bound<'_, PyModule> {}
|
||||||
|
impl Sealed for Bound<'_, PySequence> {}
|
||||||
|
impl Sealed for Bound<'_, PySet> {}
|
||||||
|
impl Sealed for Bound<'_, PySlice> {}
|
||||||
|
impl Sealed for Bound<'_, PyString> {}
|
||||||
|
impl Sealed for Bound<'_, PyTraceback> {}
|
||||||
|
impl Sealed for Bound<'_, PyTuple> {}
|
||||||
|
impl Sealed for Bound<'_, PyType> {}
|
|
@ -939,7 +939,7 @@ impl PyAny {
|
||||||
/// It is recommended you import this trait via `use pyo3::prelude::*` rather than
|
/// It is recommended you import this trait via `use pyo3::prelude::*` rather than
|
||||||
/// by importing this trait directly.
|
/// by importing this trait directly.
|
||||||
#[doc(alias = "PyAny")]
|
#[doc(alias = "PyAny")]
|
||||||
pub trait PyAnyMethods<'py> {
|
pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns whether `self` and `other` point to the same object. To compare
|
/// Returns whether `self` and `other` point to the same object. To compare
|
||||||
/// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq).
|
/// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq).
|
||||||
///
|
///
|
||||||
|
|
|
@ -55,7 +55,7 @@ impl PyBool {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyBool")]
|
#[doc(alias = "PyBool")]
|
||||||
pub trait PyBoolMethods<'py> {
|
pub trait PyBoolMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets whether this boolean is `true`.
|
/// Gets whether this boolean is `true`.
|
||||||
fn is_true(&self) -> bool;
|
fn is_true(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,7 +293,7 @@ impl PyByteArray {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyByteArray")]
|
#[doc(alias = "PyByteArray")]
|
||||||
pub trait PyByteArrayMethods<'py> {
|
pub trait PyByteArrayMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets the length of the bytearray.
|
/// Gets the length of the bytearray.
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ impl PyBytes {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyBytes")]
|
#[doc(alias = "PyBytes")]
|
||||||
pub trait PyBytesMethods<'py> {
|
pub trait PyBytesMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets the Python string as a byte slice.
|
/// Gets the Python string as a byte slice.
|
||||||
fn as_bytes(&self) -> &[u8];
|
fn as_bytes(&self) -> &[u8];
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ impl PyCapsule {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyCapsule")]
|
#[doc(alias = "PyCapsule")]
|
||||||
pub trait PyCapsuleMethods<'py> {
|
pub trait PyCapsuleMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Sets the context pointer in the capsule.
|
/// Sets the context pointer in the capsule.
|
||||||
///
|
///
|
||||||
/// Returns an error if this capsule is not valid.
|
/// Returns an error if this capsule is not valid.
|
||||||
|
|
|
@ -258,7 +258,7 @@ mod not_limited_impls {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyComplex")]
|
#[doc(alias = "PyComplex")]
|
||||||
pub trait PyComplexMethods<'py> {
|
pub trait PyComplexMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the real part of the complex number.
|
/// Returns the real part of the complex number.
|
||||||
fn real(&self) -> c_double;
|
fn real(&self) -> c_double;
|
||||||
/// Returns the imaginary part of the complex number.
|
/// Returns the imaginary part of the complex number.
|
||||||
|
|
|
@ -290,7 +290,7 @@ impl PyDict {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyDict")]
|
#[doc(alias = "PyDict")]
|
||||||
pub trait PyDictMethods<'py> {
|
pub trait PyDictMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns a new dictionary that contains the same key-value pairs as self.
|
/// Returns a new dictionary that contains the same key-value pairs as self.
|
||||||
///
|
///
|
||||||
/// This is equivalent to the Python expression `self.copy()`.
|
/// This is equivalent to the Python expression `self.copy()`.
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl PyFloat {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyFloat")]
|
#[doc(alias = "PyFloat")]
|
||||||
pub trait PyFloatMethods<'py> {
|
pub trait PyFloatMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets the value of this float.
|
/// Gets the value of this float.
|
||||||
fn value(&self) -> c_double;
|
fn value(&self) -> c_double;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ impl PyFrozenSet {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyFrozenSet")]
|
#[doc(alias = "PyFrozenSet")]
|
||||||
pub trait PyFrozenSetMethods<'py> {
|
pub trait PyFrozenSetMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the number of items in the set.
|
/// Returns the number of items in the set.
|
||||||
///
|
///
|
||||||
/// This is equivalent to the Python expression `len(self)`.
|
/// This is equivalent to the Python expression `len(self)`.
|
||||||
|
|
|
@ -285,7 +285,7 @@ index_impls!(PyList, "list", PyList::len, PyList::get_slice);
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyList")]
|
#[doc(alias = "PyList")]
|
||||||
pub trait PyListMethods<'py> {
|
pub trait PyListMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the length of the list.
|
/// Returns the length of the list.
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ impl PyMapping {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyMapping")]
|
#[doc(alias = "PyMapping")]
|
||||||
pub trait PyMappingMethods<'py> {
|
pub trait PyMappingMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the number of objects in the mapping.
|
/// Returns the number of objects in the mapping.
|
||||||
///
|
///
|
||||||
/// This is equivalent to the Python expression `len(self)`.
|
/// This is equivalent to the Python expression `len(self)`.
|
||||||
|
|
|
@ -410,7 +410,7 @@ impl PyModule {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyModule")]
|
#[doc(alias = "PyModule")]
|
||||||
pub trait PyModuleMethods<'py> {
|
pub trait PyModuleMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the module's `__dict__` attribute, which contains the module's symbol table.
|
/// Returns the module's `__dict__` attribute, which contains the module's symbol table.
|
||||||
fn dict(&self) -> Bound<'py, PyDict>;
|
fn dict(&self) -> Bound<'py, PyDict>;
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ impl PySequence {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PySequence")]
|
#[doc(alias = "PySequence")]
|
||||||
pub trait PySequenceMethods<'py> {
|
pub trait PySequenceMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Returns the number of objects in sequence.
|
/// Returns the number of objects in sequence.
|
||||||
///
|
///
|
||||||
/// This is equivalent to the Python expression `len(self)`.
|
/// This is equivalent to the Python expression `len(self)`.
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl PySet {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PySet")]
|
#[doc(alias = "PySet")]
|
||||||
pub trait PySetMethods<'py> {
|
pub trait PySetMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Removes all elements from the set.
|
/// Removes all elements from the set.
|
||||||
fn clear(&self);
|
fn clear(&self);
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl PySlice {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PySlice")]
|
#[doc(alias = "PySlice")]
|
||||||
pub trait PySliceMethods<'py> {
|
pub trait PySliceMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Retrieves the start, stop, and step indices from the slice object,
|
/// Retrieves the start, stop, and step indices from the slice object,
|
||||||
/// assuming a sequence of length `length`, and stores the length of the
|
/// assuming a sequence of length `length`, and stores the length of the
|
||||||
/// slice in its `slicelength` member.
|
/// slice in its `slicelength` member.
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl PyString {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyString")]
|
#[doc(alias = "PyString")]
|
||||||
pub trait PyStringMethods<'py> {
|
pub trait PyStringMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets the Python string as a Rust UTF-8 string slice.
|
/// Gets the Python string as a Rust UTF-8 string slice.
|
||||||
///
|
///
|
||||||
/// Returns a `UnicodeEncodeError` if the input is not valid unicode
|
/// Returns a `UnicodeEncodeError` if the input is not valid unicode
|
||||||
|
|
|
@ -56,7 +56,7 @@ impl PyTraceback {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyTraceback")]
|
#[doc(alias = "PyTraceback")]
|
||||||
pub trait PyTracebackMethods<'py> {
|
pub trait PyTracebackMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Formats the traceback as a string.
|
/// Formats the traceback as a string.
|
||||||
///
|
///
|
||||||
/// This does not include the exception type and value. The exception type and value can be
|
/// This does not include the exception type and value. The exception type and value can be
|
||||||
|
|
|
@ -248,7 +248,7 @@ index_impls!(PyTuple, "tuple", PyTuple::len, PyTuple::get_slice);
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyTuple")]
|
#[doc(alias = "PyTuple")]
|
||||||
pub trait PyTupleMethods<'py> {
|
pub trait PyTupleMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Gets the length of the tuple.
|
/// Gets the length of the tuple.
|
||||||
fn len(&self) -> usize;
|
fn len(&self) -> usize;
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl PyType {
|
||||||
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
/// syntax these methods are separated into a trait, because stable Rust does not yet support
|
||||||
/// `arbitrary_self_types`.
|
/// `arbitrary_self_types`.
|
||||||
#[doc(alias = "PyType")]
|
#[doc(alias = "PyType")]
|
||||||
pub trait PyTypeMethods<'py> {
|
pub trait PyTypeMethods<'py>: crate::sealed::Sealed {
|
||||||
/// Retrieves the underlying FFI pointer associated with this Python object.
|
/// Retrieves the underlying FFI pointer associated with this Python object.
|
||||||
fn as_type_ptr(&self) -> *mut ffi::PyTypeObject;
|
fn as_type_ptr(&self) -> *mut ffi::PyTypeObject;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue