@@ -382,11 +382,14 @@ fn impl_class(
382
382
) -> syn:: Result < TokenStream > {
383
383
let pytypeinfo_impl = impl_pytypeinfo ( cls, attr, Some ( & deprecations) ) ;
384
384
385
- let py_class_impl = PyClassImplsBuilder :: new ( cls, attr, methods_type)
386
- . doc ( doc)
387
- . impl_all ( ) ;
388
-
389
- let descriptors = impl_descriptors ( cls, field_options) ?;
385
+ let py_class_impl = PyClassImplsBuilder :: new (
386
+ cls,
387
+ attr,
388
+ methods_type,
389
+ descriptors_to_items ( cls, field_options) ?,
390
+ )
391
+ . doc ( doc)
392
+ . impl_all ( ) ;
390
393
391
394
Ok ( quote ! {
392
395
const _: ( ) = {
@@ -395,8 +398,6 @@ fn impl_class(
395
398
#pytypeinfo_impl
396
399
397
400
#py_class_impl
398
-
399
- #descriptors
400
401
} ;
401
402
} )
402
403
}
@@ -452,10 +453,14 @@ fn impl_enum_class(
452
453
krate : syn:: Path ,
453
454
) -> syn:: Result < TokenStream > {
454
455
let pytypeinfo = impl_pytypeinfo ( cls, args, None ) ;
455
- let pyclass_impls = PyClassImplsBuilder :: new ( cls, args, methods_type)
456
- . doc ( doc)
457
- . impl_all ( ) ;
458
- let descriptors = unit_variants_as_descriptors ( cls, variants. iter ( ) . map ( |v| v. ident ) ) ;
456
+ let pyclass_impls = PyClassImplsBuilder :: new (
457
+ cls,
458
+ args,
459
+ methods_type,
460
+ unit_variants_as_items ( cls, variants. iter ( ) . map ( |v| v. ident ) ) ,
461
+ )
462
+ . doc ( doc)
463
+ . impl_all ( ) ;
459
464
460
465
let default_repr_impl = {
461
466
let variants_repr = variants. iter ( ) . map ( |variant| {
@@ -487,13 +492,11 @@ fn impl_enum_class(
487
492
#pyclass_impls
488
493
489
494
#default_impls
490
-
491
- #descriptors
492
495
} ;
493
496
} )
494
497
}
495
498
496
- fn unit_variants_as_descriptors < ' a > (
499
+ fn unit_variants_as_items < ' a > (
497
500
cls : & ' a syn:: Ident ,
498
501
variant_names : impl IntoIterator < Item = & ' a syn:: Ident > ,
499
502
) -> TokenStream {
@@ -511,16 +514,9 @@ fn unit_variants_as_descriptors<'a>(
511
514
. map ( |var| gen_py_const ( & cls_type, & variant_to_attribute ( var) ) ) ;
512
515
513
516
quote ! {
514
- impl _pyo3:: impl_:: pyclass:: PyClassIntrinsicItems <#cls>
515
- for _pyo3:: impl_:: pyclass:: PyClassImplCollector <#cls>
516
- {
517
- fn pyclass_intrinsic_items( self ) -> & ' static _pyo3:: impl_:: pyclass:: PyClassItems {
518
- static ITEMS : _pyo3:: impl_:: pyclass:: PyClassItems = _pyo3:: impl_:: pyclass:: PyClassItems {
519
- methods: & [ #( #py_methods) , * ] ,
520
- slots: & [ ]
521
- } ;
522
- & ITEMS
523
- }
517
+ _pyo3:: impl_:: pyclass:: PyClassItems {
518
+ methods: & [ #( #py_methods) , * ] ,
519
+ slots: & [ ]
524
520
}
525
521
}
526
522
}
@@ -537,7 +533,7 @@ fn extract_variant_data(variant: &syn::Variant) -> syn::Result<PyClassEnumVarian
537
533
Ok ( PyClassEnumVariant { ident } )
538
534
}
539
535
540
- fn impl_descriptors (
536
+ fn descriptors_to_items (
541
537
cls : & syn:: Ident ,
542
538
field_options : Vec < ( & syn:: Field , FieldPyO3Options ) > ,
543
539
) -> syn:: Result < TokenStream > {
@@ -577,16 +573,9 @@ fn impl_descriptors(
577
573
. collect :: < syn:: Result < _ > > ( ) ?;
578
574
579
575
Ok ( quote ! {
580
- impl _pyo3:: impl_:: pyclass:: PyClassIntrinsicItems <#cls>
581
- for _pyo3:: impl_:: pyclass:: PyClassImplCollector <#cls>
582
- {
583
- fn pyclass_intrinsic_items( self ) -> & ' static _pyo3:: impl_:: pyclass:: PyClassItems {
584
- static ITEMS : _pyo3:: impl_:: pyclass:: PyClassItems = _pyo3:: impl_:: pyclass:: PyClassItems {
585
- methods: & [ #( #py_methods) , * ] ,
586
- slots: & [ ]
587
- } ;
588
- & ITEMS
589
- }
576
+ _pyo3:: impl_:: pyclass:: PyClassItems {
577
+ methods: & [ #( #py_methods) , * ] ,
578
+ slots: & [ ]
590
579
}
591
580
} )
592
581
}
@@ -632,15 +621,22 @@ struct PyClassImplsBuilder<'a> {
632
621
cls : & ' a syn:: Ident ,
633
622
attr : & ' a PyClassArgs ,
634
623
methods_type : PyClassMethodsType ,
624
+ default_items : TokenStream ,
635
625
doc : Option < PythonDoc > ,
636
626
}
637
627
638
628
impl < ' a > PyClassImplsBuilder < ' a > {
639
- fn new ( cls : & ' a syn:: Ident , attr : & ' a PyClassArgs , methods_type : PyClassMethodsType ) -> Self {
629
+ fn new (
630
+ cls : & ' a syn:: Ident ,
631
+ attr : & ' a PyClassArgs ,
632
+ methods_type : PyClassMethodsType ,
633
+ default_items : TokenStream ,
634
+ ) -> Self {
640
635
Self {
641
636
cls,
642
637
attr,
643
638
methods_type,
639
+ default_items,
644
640
doc : None ,
645
641
}
646
642
}
@@ -802,6 +798,8 @@ impl<'a> PyClassImplsBuilder<'a> {
802
798
None
803
799
} ;
804
800
801
+ let default_items = & self . default_items ;
802
+
805
803
quote ! {
806
804
impl _pyo3:: impl_:: pyclass:: PyClassImpl for #cls {
807
805
const DOC : & ' static str = #doc;
@@ -817,7 +815,8 @@ impl<'a> PyClassImplsBuilder<'a> {
817
815
fn for_all_items( visitor: & mut dyn :: std:: ops:: FnMut ( & _pyo3:: impl_:: pyclass:: PyClassItems ) ) {
818
816
use _pyo3:: impl_:: pyclass:: * ;
819
817
let collector = PyClassImplCollector :: <Self >:: new( ) ;
820
- visitor( collector. pyclass_intrinsic_items( ) ) ;
818
+ static INTRINSIC_ITEMS : PyClassItems = #default_items;
819
+ visitor( & INTRINSIC_ITEMS ) ;
821
820
// This depends on Python implementation detail;
822
821
// an old slot entry will be overriden by newer ones.
823
822
visitor( collector. pyclass_default_items( ) ) ;
0 commit comments