Skip to content

Commit e39881c

Browse files
committed
refactor: inline pyclass_intrinsic_items
1 parent fc2b0f8 commit e39881c

File tree

3 files changed

+38
-41
lines changed

3 files changed

+38
-41
lines changed

guide/src/class.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,8 +861,9 @@ impl pyo3::impl_::pyclass::PyClassImpl for MyClass {
861861
fn for_all_items(visitor: &mut dyn FnMut(&pyo3::impl_::pyclass::PyClassItems)) {
862862
use pyo3::impl_::pyclass::*;
863863
let collector = PyClassImplCollector::<MyClass>::new();
864+
static INTRINSIC_ITEMS: &PyClassItems = PyClassItems { slots: &[], methods: &[] };
865+
visitor(&INTRINSIC_ITEMS);
864866
visitor(collector.py_methods());
865-
visitor(collector.pyclass_intrinsic_items());
866867
}
867868
fn get_new() -> Option<pyo3::ffi::newfunc> {
868869
use pyo3::impl_::pyclass::*;

pyo3-macros-backend/src/pyclass.rs

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -382,11 +382,14 @@ fn impl_class(
382382
) -> syn::Result<TokenStream> {
383383
let pytypeinfo_impl = impl_pytypeinfo(cls, attr, Some(&deprecations));
384384

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();
390393

391394
Ok(quote! {
392395
const _: () = {
@@ -395,8 +398,6 @@ fn impl_class(
395398
#pytypeinfo_impl
396399

397400
#py_class_impl
398-
399-
#descriptors
400401
};
401402
})
402403
}
@@ -452,10 +453,14 @@ fn impl_enum_class(
452453
krate: syn::Path,
453454
) -> syn::Result<TokenStream> {
454455
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();
459464

460465
let default_repr_impl = {
461466
let variants_repr = variants.iter().map(|variant| {
@@ -487,13 +492,11 @@ fn impl_enum_class(
487492
#pyclass_impls
488493

489494
#default_impls
490-
491-
#descriptors
492495
};
493496
})
494497
}
495498

496-
fn unit_variants_as_descriptors<'a>(
499+
fn unit_variants_as_items<'a>(
497500
cls: &'a syn::Ident,
498501
variant_names: impl IntoIterator<Item = &'a syn::Ident>,
499502
) -> TokenStream {
@@ -511,16 +514,9 @@ fn unit_variants_as_descriptors<'a>(
511514
.map(|var| gen_py_const(&cls_type, &variant_to_attribute(var)));
512515

513516
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: &[]
524520
}
525521
}
526522
}
@@ -537,7 +533,7 @@ fn extract_variant_data(variant: &syn::Variant) -> syn::Result<PyClassEnumVarian
537533
Ok(PyClassEnumVariant { ident })
538534
}
539535

540-
fn impl_descriptors(
536+
fn descriptors_to_items(
541537
cls: &syn::Ident,
542538
field_options: Vec<(&syn::Field, FieldPyO3Options)>,
543539
) -> syn::Result<TokenStream> {
@@ -577,16 +573,9 @@ fn impl_descriptors(
577573
.collect::<syn::Result<_>>()?;
578574

579575
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: &[]
590579
}
591580
})
592581
}
@@ -632,15 +621,22 @@ struct PyClassImplsBuilder<'a> {
632621
cls: &'a syn::Ident,
633622
attr: &'a PyClassArgs,
634623
methods_type: PyClassMethodsType,
624+
default_items: TokenStream,
635625
doc: Option<PythonDoc>,
636626
}
637627

638628
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 {
640635
Self {
641636
cls,
642637
attr,
643638
methods_type,
639+
default_items,
644640
doc: None,
645641
}
646642
}
@@ -802,6 +798,8 @@ impl<'a> PyClassImplsBuilder<'a> {
802798
None
803799
};
804800

801+
let default_items = &self.default_items;
802+
805803
quote! {
806804
impl _pyo3::impl_::pyclass::PyClassImpl for #cls {
807805
const DOC: &'static str = #doc;
@@ -817,7 +815,8 @@ impl<'a> PyClassImplsBuilder<'a> {
817815
fn for_all_items(visitor: &mut dyn ::std::ops::FnMut(& _pyo3::impl_::pyclass::PyClassItems)) {
818816
use _pyo3::impl_::pyclass::*;
819817
let collector = PyClassImplCollector::<Self>::new();
820-
visitor(collector.pyclass_intrinsic_items());
818+
static INTRINSIC_ITEMS: PyClassItems = #default_items;
819+
visitor(&INTRINSIC_ITEMS);
821820
// This depends on Python implementation detail;
822821
// an old slot entry will be overriden by newer ones.
823822
visitor(collector.pyclass_default_items());

src/impl_/pyclass.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,6 @@ pub trait PyClassInventory: inventory::Collect {
736736
fn items(&'static self) -> &'static PyClassItems;
737737
}
738738

739-
// Methods from #[pyo3(get, set)] on struct fields.
740-
items_trait!(PyClassIntrinsicItems, pyclass_intrinsic_items);
741-
742739
// Items from #[pymethods] if not using inventory.
743740
#[cfg(not(feature = "multiple-pymethods"))]
744741
items_trait!(PyMethods, py_methods);

0 commit comments

Comments
 (0)