diff --git a/src/ffi_ptr_ext.rs b/src/ffi_ptr_ext.rs index 8a45f5d7..3ca8671f 100644 --- a/src/ffi_ptr_ext.rs +++ b/src/ffi_ptr_ext.rs @@ -1,19 +1,10 @@ +use crate::sealed::Sealed; use crate::{ ffi, instance::{Borrowed, Bound}, PyAny, PyResult, Python, }; -mod sealed { - use super::*; - - pub trait Sealed {} - - impl Sealed for *mut ffi::PyObject {} -} - -use sealed::Sealed; - pub(crate) trait FfiPtrExt: Sealed { unsafe fn assume_owned_or_err(self, py: Python<'_>) -> PyResult>; unsafe fn assume_owned_or_opt(self, py: Python<'_>) -> Option>; diff --git a/src/lib.rs b/src/lib.rs index d0c53c4a..17dbd972 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -324,6 +324,7 @@ pub use crate::version::PythonVersionInfo; pub(crate) mod ffi_ptr_ext; pub(crate) mod py_result_ext; +pub(crate) mod sealed; /// Old module which contained some implementation details of the `#[pyproto]` module. /// diff --git a/src/py_result_ext.rs b/src/py_result_ext.rs index 66309988..2ad079ed 100644 --- a/src/py_result_ext.rs +++ b/src/py_result_ext.rs @@ -1,16 +1,6 @@ use crate::{types::any::PyAnyMethods, Bound, PyAny, PyResult, PyTypeCheck}; -mod sealed { - use super::*; - - pub trait Sealed {} - - impl Sealed for PyResult> {} -} - -use sealed::Sealed; - -pub(crate) trait PyResultExt<'py>: Sealed { +pub(crate) trait PyResultExt<'py>: crate::sealed::Sealed { fn downcast_into(self) -> PyResult>; unsafe fn downcast_into_unchecked(self) -> PyResult>; } diff --git a/src/sealed.rs b/src/sealed.rs new file mode 100644 index 00000000..e2d5c5cc --- /dev/null +++ b/src/sealed.rs @@ -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> {} + +// 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> {} diff --git a/src/types/any.rs b/src/types/any.rs index 15f2fd31..0207217b 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -939,7 +939,7 @@ impl PyAny { /// It is recommended you import this trait via `use pyo3::prelude::*` rather than /// by importing this trait directly. #[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 /// the equality of two objects (the `==` operator), use [`eq`](PyAny::eq). /// diff --git a/src/types/boolobject.rs b/src/types/boolobject.rs index 906a9670..3a2f60f6 100644 --- a/src/types/boolobject.rs +++ b/src/types/boolobject.rs @@ -55,7 +55,7 @@ impl PyBool { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyBool")] -pub trait PyBoolMethods<'py> { +pub trait PyBoolMethods<'py>: crate::sealed::Sealed { /// Gets whether this boolean is `true`. fn is_true(&self) -> bool; } diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index 2a21509d..a860b4d4 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -293,7 +293,7 @@ impl PyByteArray { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyByteArray")] -pub trait PyByteArrayMethods<'py> { +pub trait PyByteArrayMethods<'py>: crate::sealed::Sealed { /// Gets the length of the bytearray. fn len(&self) -> usize; diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 0861af63..2a54c172 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -143,7 +143,7 @@ impl PyBytes { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyBytes")] -pub trait PyBytesMethods<'py> { +pub trait PyBytesMethods<'py>: crate::sealed::Sealed { /// Gets the Python string as a byte slice. fn as_bytes(&self) -> &[u8]; } diff --git a/src/types/capsule.rs b/src/types/capsule.rs index aa1a910d..fe5a47e1 100644 --- a/src/types/capsule.rs +++ b/src/types/capsule.rs @@ -263,7 +263,7 @@ impl PyCapsule { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyCapsule")] -pub trait PyCapsuleMethods<'py> { +pub trait PyCapsuleMethods<'py>: crate::sealed::Sealed { /// Sets the context pointer in the capsule. /// /// Returns an error if this capsule is not valid. diff --git a/src/types/complex.rs b/src/types/complex.rs index 6d4bc7a2..80ecffdc 100644 --- a/src/types/complex.rs +++ b/src/types/complex.rs @@ -258,7 +258,7 @@ mod not_limited_impls { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyComplex")] -pub trait PyComplexMethods<'py> { +pub trait PyComplexMethods<'py>: crate::sealed::Sealed { /// Returns the real part of the complex number. fn real(&self) -> c_double; /// Returns the imaginary part of the complex number. diff --git a/src/types/dict.rs b/src/types/dict.rs index daae753c..5d124346 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -290,7 +290,7 @@ impl PyDict { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[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. /// /// This is equivalent to the Python expression `self.copy()`. diff --git a/src/types/float.rs b/src/types/float.rs index 766c597b..6db1fdae 100644 --- a/src/types/float.rs +++ b/src/types/float.rs @@ -58,7 +58,7 @@ impl PyFloat { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyFloat")] -pub trait PyFloatMethods<'py> { +pub trait PyFloatMethods<'py>: crate::sealed::Sealed { /// Gets the value of this float. fn value(&self) -> c_double; } diff --git a/src/types/frozenset.rs b/src/types/frozenset.rs index 15f89258..cc16a934 100644 --- a/src/types/frozenset.rs +++ b/src/types/frozenset.rs @@ -157,7 +157,7 @@ impl PyFrozenSet { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyFrozenSet")] -pub trait PyFrozenSetMethods<'py> { +pub trait PyFrozenSetMethods<'py>: crate::sealed::Sealed { /// Returns the number of items in the set. /// /// This is equivalent to the Python expression `len(self)`. diff --git a/src/types/list.rs b/src/types/list.rs index 3e3942bc..a8df26dd 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -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 /// `arbitrary_self_types`. #[doc(alias = "PyList")] -pub trait PyListMethods<'py> { +pub trait PyListMethods<'py>: crate::sealed::Sealed { /// Returns the length of the list. fn len(&self) -> usize; diff --git a/src/types/mapping.rs b/src/types/mapping.rs index afbdae68..a5a93163 100644 --- a/src/types/mapping.rs +++ b/src/types/mapping.rs @@ -109,7 +109,7 @@ impl PyMapping { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyMapping")] -pub trait PyMappingMethods<'py> { +pub trait PyMappingMethods<'py>: crate::sealed::Sealed { /// Returns the number of objects in the mapping. /// /// This is equivalent to the Python expression `len(self)`. diff --git a/src/types/module.rs b/src/types/module.rs index 75fc6625..693df79c 100644 --- a/src/types/module.rs +++ b/src/types/module.rs @@ -410,7 +410,7 @@ impl PyModule { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[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. fn dict(&self) -> Bound<'py, PyDict>; diff --git a/src/types/sequence.rs b/src/types/sequence.rs index 80306cbf..62abb66f 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -192,7 +192,7 @@ impl PySequence { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PySequence")] -pub trait PySequenceMethods<'py> { +pub trait PySequenceMethods<'py>: crate::sealed::Sealed { /// Returns the number of objects in sequence. /// /// This is equivalent to the Python expression `len(self)`. diff --git a/src/types/set.rs b/src/types/set.rs index 0c173352..8e36ab81 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -139,7 +139,7 @@ impl PySet { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PySet")] -pub trait PySetMethods<'py> { +pub trait PySetMethods<'py>: crate::sealed::Sealed { /// Removes all elements from the set. fn clear(&self); diff --git a/src/types/slice.rs b/src/types/slice.rs index b4b6731d..8e754520 100644 --- a/src/types/slice.rs +++ b/src/types/slice.rs @@ -105,7 +105,7 @@ impl PySlice { /// 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> { +pub trait PySliceMethods<'py>: crate::sealed::Sealed { /// 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. diff --git a/src/types/string.rs b/src/types/string.rs index 88ebb30b..93f3682c 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -282,7 +282,7 @@ impl PyString { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[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. /// /// Returns a `UnicodeEncodeError` if the input is not valid unicode diff --git a/src/types/traceback.rs b/src/types/traceback.rs index b8782463..c4cedd79 100644 --- a/src/types/traceback.rs +++ b/src/types/traceback.rs @@ -56,7 +56,7 @@ impl PyTraceback { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyTraceback")] -pub trait PyTracebackMethods<'py> { +pub trait PyTracebackMethods<'py>: crate::sealed::Sealed { /// Formats the traceback as a string. /// /// This does not include the exception type and value. The exception type and value can be diff --git a/src/types/tuple.rs b/src/types/tuple.rs index 51d33f93..3ffaf9c3 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -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 /// `arbitrary_self_types`. #[doc(alias = "PyTuple")] -pub trait PyTupleMethods<'py> { +pub trait PyTupleMethods<'py>: crate::sealed::Sealed { /// Gets the length of the tuple. fn len(&self) -> usize; diff --git a/src/types/typeobject.rs b/src/types/typeobject.rs index 4c1b17a2..d75e39d0 100644 --- a/src/types/typeobject.rs +++ b/src/types/typeobject.rs @@ -107,7 +107,7 @@ impl PyType { /// syntax these methods are separated into a trait, because stable Rust does not yet support /// `arbitrary_self_types`. #[doc(alias = "PyType")] -pub trait PyTypeMethods<'py> { +pub trait PyTypeMethods<'py>: crate::sealed::Sealed { /// Retrieves the underlying FFI pointer associated with this Python object. fn as_type_ptr(&self) -> *mut ffi::PyTypeObject;