@@ -238,6 +238,14 @@ pub trait PyClassImpl: Sized + 'static {
238238 fn lazy_type_object ( ) -> & ' static LazyTypeObject < Self > ;
239239}
240240
241+ mod generic_pyclass {
242+ use crate :: PyClass ;
243+
244+ pub trait Sealed { }
245+
246+ impl < T : PyClass > Sealed for T { }
247+ }
248+
241249/// Iterator used to process all class items during type instantiation.
242250pub struct PyClassItemsIter {
243251 /// Iteration state
@@ -305,7 +313,7 @@ impl Iterator for PyClassItemsIter {
305313macro_rules! slot_fragment_trait {
306314 ( $trait_name: ident, $( $default_method: tt) * ) => {
307315 #[ allow( non_camel_case_types, reason = "to match Python dunder names" ) ]
308- pub trait $trait_name<T >: Sized {
316+ pub trait $trait_name<T >: Sized + pymethods :: Sealed {
309317 $( $default_method) *
310318 }
311319
@@ -896,7 +904,7 @@ pub use generate_pyclass_richcompare_slot;
896904///
897905/// Do not implement this trait manually. Instead, use `#[pyclass(freelist = N)]`
898906/// on a Rust struct to implement it.
899- pub trait PyClassWithFreeList : PyClass {
907+ pub trait PyClassWithFreeList : PyClass + generic_pyclass :: Sealed {
900908 fn get_free_list ( py : Python < ' _ > ) -> & ' static Mutex < PyObjectFreeList > ;
901909}
902910
@@ -971,7 +979,7 @@ pub trait PyClassInventory: inventory::Collect {
971979
972980// Items from #[pymethods] if not using inventory.
973981#[ cfg( not( feature = "multiple-pymethods" ) ) ]
974- pub trait PyMethods < T > {
982+ pub trait PyMethods < T > : pymethods :: Sealed {
975983 fn py_methods ( self ) -> & ' static PyClassItems ;
976984}
977985
@@ -985,6 +993,15 @@ impl<T> PyMethods<T> for &'_ PyClassImplCollector<T> {
985993 }
986994}
987995
996+ mod pymethods {
997+ use crate :: impl_:: pyclass:: PyClassImplCollector ;
998+
999+ pub trait Sealed { }
1000+
1001+ impl < T > Sealed for & PyClassImplCollector < T > { }
1002+ impl < T > Sealed for PyClassImplCollector < T > { }
1003+ }
1004+
9881005// Thread checkers
9891006
9901007#[ doc( hidden) ]
@@ -1277,7 +1294,7 @@ where
12771294 label = "required by `#[pyo3(get)]` to create a readable property from a field of type `{Self}`" ,
12781295 note = "implement `IntoPyObject` for `&{Self}` or `IntoPyObject + Clone` for `{Self}` to define the conversion"
12791296) ]
1280- pub trait PyO3GetField < ' py > : IntoPyObject < ' py > + Clone { }
1297+ pub trait PyO3GetField < ' py > : IntoPyObject < ' py > + Clone + pyo3_get_field :: Sealed { }
12811298impl < ' py , T > PyO3GetField < ' py > for T where T : IntoPyObject < ' py > + Clone { }
12821299
12831300/// Base case attempts to use IntoPyObject + Clone
@@ -1298,6 +1315,14 @@ impl<ClassT: PyClass, FieldT, const OFFSET: usize, const IMPLEMENTS_INTOPYOBJECT
12981315 }
12991316}
13001317
1318+ mod pyo3_get_field {
1319+ use crate :: IntoPyObject ;
1320+
1321+ pub trait Sealed { }
1322+
1323+ impl < ' py , T : IntoPyObject < ' py > > Sealed for T { }
1324+ }
1325+
13011326/// ensures `obj` is not mutably aliased
13021327#[ inline]
13031328unsafe fn ensure_no_mutable_alias < ' a , ClassT : PyClass > (
@@ -1413,7 +1438,7 @@ impl<const IMPLEMENTS_INTOPYOBJECT: bool> ConvertField<false, IMPLEMENTS_INTOPYO
14131438 }
14141439}
14151440
1416- pub trait ExtractPyClassWithClone { }
1441+ pub trait ExtractPyClassWithClone : generic_pyclass :: Sealed { }
14171442
14181443#[ cfg( test) ]
14191444#[ cfg( feature = "macros" ) ]
0 commit comments