@@ -594,7 +594,6 @@ impl<'a> PyClassImplsBuilder<'a> {
594
594
self . impl_pyclass( ) ,
595
595
self . impl_extractext( ) ,
596
596
self . impl_into_py( ) ,
597
- self . impl_methods_inventory( ) ,
598
597
self . impl_pyclassimpl( ) ,
599
598
self . impl_freelist( ) ,
600
599
self . impl_gc( ) ,
@@ -667,48 +666,6 @@ impl<'a> PyClassImplsBuilder<'a> {
667
666
quote ! { }
668
667
}
669
668
}
670
-
671
- /// To allow multiple #[pymethods] block, we define inventory types.
672
- fn impl_methods_inventory ( & self ) -> TokenStream {
673
- let cls = self . cls ;
674
- let methods_type = self . methods_type ;
675
- match methods_type {
676
- PyClassMethodsType :: Specialization => quote ! { } ,
677
- PyClassMethodsType :: Inventory => {
678
- // Try to build a unique type for better error messages
679
- let name = format ! ( "Pyo3MethodsInventoryFor{}" , cls. unraw( ) ) ;
680
- let inventory_cls = syn:: Ident :: new ( & name, Span :: call_site ( ) ) ;
681
-
682
- quote ! {
683
- #[ doc( hidden) ]
684
- pub struct #inventory_cls {
685
- methods: :: std:: vec:: Vec <:: pyo3:: class:: PyMethodDefType >,
686
- slots: :: std:: vec:: Vec <:: pyo3:: ffi:: PyType_Slot >,
687
- }
688
- impl :: pyo3:: class:: impl_:: PyMethodsInventory for #inventory_cls {
689
- fn new(
690
- methods: :: std:: vec:: Vec <:: pyo3:: class:: PyMethodDefType >,
691
- slots: :: std:: vec:: Vec <:: pyo3:: ffi:: PyType_Slot >,
692
- ) -> Self {
693
- Self { methods, slots }
694
- }
695
- fn methods( & ' static self ) -> & ' static [ :: pyo3:: class:: PyMethodDefType ] {
696
- & self . methods
697
- }
698
- fn slots( & ' static self ) -> & ' static [ :: pyo3:: ffi:: PyType_Slot ] {
699
- & self . slots
700
- }
701
- }
702
-
703
- impl :: pyo3:: class:: impl_:: HasMethodsInventory for #cls {
704
- type Methods = #inventory_cls;
705
- }
706
-
707
- :: pyo3:: inventory:: collect!( #inventory_cls) ;
708
- }
709
- }
710
- }
711
- }
712
669
fn impl_pyclassimpl ( & self ) -> TokenStream {
713
670
let cls = self . cls ;
714
671
let doc = self . doc . as_ref ( ) . map_or ( quote ! { "\0 " } , |doc| quote ! { #doc} ) ;
@@ -727,26 +684,37 @@ impl<'a> PyClassImplsBuilder<'a> {
727
684
quote ! { :: pyo3:: class:: impl_:: ThreadCheckerStub <#cls> }
728
685
} ;
729
686
730
- let methods_protos = match self . methods_type {
731
- PyClassMethodsType :: Specialization => {
732
- quote ! { visitor( collector. methods_protocol_slots( ) ) ; }
733
- }
687
+ let ( for_each_py_method, methods_protos, inventory, inventory_class) = match self
688
+ . methods_type
689
+ {
690
+ PyClassMethodsType :: Specialization => (
691
+ quote ! { visitor( collector. py_methods( ) ) ; } ,
692
+ quote ! { visitor( collector. methods_protocol_slots( ) ) ; } ,
693
+ None ,
694
+ None ,
695
+ ) ,
734
696
PyClassMethodsType :: Inventory => {
735
- quote ! {
736
- for inventory in :: pyo3:: inventory:: iter:: <<Self as :: pyo3:: class:: impl_:: HasMethodsInventory >:: Methods >( ) {
737
- visitor( :: pyo3:: class:: impl_:: PyMethodsInventory :: slots( inventory) ) ;
738
- }
739
- }
697
+ // To allow multiple #[pymethods] block, we define inventory types.
698
+ let inventory_class_name = syn:: Ident :: new (
699
+ & format ! ( "Pyo3MethodsInventoryFor{}" , cls. unraw( ) ) ,
700
+ Span :: call_site ( ) ,
701
+ ) ;
702
+ (
703
+ quote ! {
704
+ for inventory in :: pyo3:: inventory:: iter:: <<Self as :: pyo3:: class:: impl_:: PyClassImpl >:: Inventory >( ) {
705
+ visitor( :: pyo3:: class:: impl_:: PyClassInventory :: methods( inventory) ) ;
706
+ }
707
+ } ,
708
+ quote ! {
709
+ for inventory in :: pyo3:: inventory:: iter:: <<Self as :: pyo3:: class:: impl_:: PyClassImpl >:: Inventory >( ) {
710
+ visitor( :: pyo3:: class:: impl_:: PyClassInventory :: slots( inventory) ) ;
711
+ }
712
+ } ,
713
+ Some ( quote ! { type Inventory = #inventory_class_name; } ) ,
714
+ Some ( define_inventory_class ( & inventory_class_name) ) ,
715
+ )
740
716
}
741
717
} ;
742
- let for_each_py_method = match self . methods_type {
743
- PyClassMethodsType :: Specialization => quote ! { visitor( collector. py_methods( ) ) ; } ,
744
- PyClassMethodsType :: Inventory => quote ! {
745
- for inventory in :: pyo3:: inventory:: iter:: <<Self as :: pyo3:: class:: impl_:: HasMethodsInventory >:: Methods >( ) {
746
- visitor( :: pyo3:: class:: impl_:: PyMethodsInventory :: methods( inventory) ) ;
747
- }
748
- } ,
749
- } ;
750
718
quote ! {
751
719
impl :: pyo3:: class:: impl_:: PyClassImpl for #cls {
752
720
const DOC : & ' static str = #doc;
@@ -757,6 +725,7 @@ impl<'a> PyClassImplsBuilder<'a> {
757
725
type Layout = :: pyo3:: PyCell <Self >;
758
726
type BaseType = #base;
759
727
type ThreadChecker = #thread_checker;
728
+ #inventory
760
729
761
730
fn for_each_method_def( visitor: & mut dyn :: std:: ops:: FnMut ( & [ :: pyo3:: class:: PyMethodDefType ] ) ) {
762
731
use :: pyo3:: class:: impl_:: * ;
@@ -807,6 +776,8 @@ impl<'a> PyClassImplsBuilder<'a> {
807
776
collector. buffer_procs( )
808
777
}
809
778
}
779
+
780
+ #inventory_class
810
781
}
811
782
}
812
783
@@ -865,3 +836,36 @@ impl<'a> PyClassImplsBuilder<'a> {
865
836
}
866
837
}
867
838
}
839
+
840
+ fn define_inventory_class ( inventory_class_name : & syn:: Ident ) -> TokenStream {
841
+ quote ! {
842
+ #[ doc( hidden) ]
843
+ pub struct #inventory_class_name {
844
+ methods: & ' static [ :: pyo3:: class:: PyMethodDefType ] ,
845
+ slots: & ' static [ :: pyo3:: ffi:: PyType_Slot ] ,
846
+ }
847
+ impl #inventory_class_name {
848
+ const fn new(
849
+ methods: & ' static [ :: pyo3:: class:: PyMethodDefType ] ,
850
+ slots: & ' static [ :: pyo3:: ffi:: PyType_Slot ] ,
851
+ ) -> Self {
852
+ Self { methods, slots }
853
+ }
854
+ }
855
+
856
+ impl :: pyo3:: class:: impl_:: PyClassInventory for #inventory_class_name {
857
+ fn methods( & ' static self ) -> & ' static [ :: pyo3:: class:: PyMethodDefType ] {
858
+ self . methods
859
+ }
860
+ fn slots( & ' static self ) -> & ' static [ :: pyo3:: ffi:: PyType_Slot ] {
861
+ self . slots
862
+ }
863
+ }
864
+
865
+ // inventory requires these bounds
866
+ unsafe impl :: std:: marker:: Send for #inventory_class_name { }
867
+ unsafe impl :: std:: marker:: Sync for #inventory_class_name { }
868
+
869
+ :: pyo3:: inventory:: collect!( #inventory_class_name) ;
870
+ }
871
+ }
0 commit comments