refactor: inline pyclass_default_items trait
This commit is contained in:
parent
ada301773e
commit
4d471077b4
|
@ -497,23 +497,15 @@ fn impl_enum_class(
|
|||
let cls = enum_.ident;
|
||||
let variants = enum_.variants;
|
||||
let pytypeinfo = impl_pytypeinfo(cls, args, None);
|
||||
let pyclass_impls = PyClassImplsBuilder::new(
|
||||
cls,
|
||||
args,
|
||||
methods_type,
|
||||
unit_variants_as_items(cls, variants.iter().map(|v| v.ident)),
|
||||
)
|
||||
.doc(doc)
|
||||
.impl_all();
|
||||
|
||||
let default_repr_impl = {
|
||||
let default_repr_impl: syn::ImplItemMethod = {
|
||||
let variants_repr = variants.iter().map(|variant| {
|
||||
let variant_name = variant.ident;
|
||||
// Assuming all variants are unit variants because they are the only type we support.
|
||||
let repr = format!("{}.{}", cls, variant_name);
|
||||
quote! { #cls::#variant_name => #repr, }
|
||||
});
|
||||
quote! {
|
||||
syn::parse_quote! {
|
||||
#[doc(hidden)]
|
||||
#[allow(non_snake_case)]
|
||||
#[pyo3(name = "__repr__")]
|
||||
|
@ -533,7 +525,7 @@ fn impl_enum_class(
|
|||
let variant_name = variant.ident;
|
||||
quote! { #cls::#variant_name => #cls::#variant_name as #repr_type, }
|
||||
});
|
||||
quote! {
|
||||
syn::parse_quote! {
|
||||
#[doc(hidden)]
|
||||
#[allow(non_snake_case)]
|
||||
#[pyo3(name = "__int__")]
|
||||
|
@ -553,7 +545,7 @@ fn impl_enum_class(
|
|||
Ok(true.to_object(py)),
|
||||
}
|
||||
});
|
||||
quote! {
|
||||
syn::parse_quote! {
|
||||
#[doc(hidden)]
|
||||
#[allow(non_snake_case)]
|
||||
#[pyo3(name = "__richcmp__")]
|
||||
|
@ -584,8 +576,16 @@ fn impl_enum_class(
|
|||
}
|
||||
};
|
||||
|
||||
let default_items =
|
||||
gen_default_items(cls, vec![default_repr_impl, default_richcmp, default_int]);
|
||||
let mut default_methods = vec![default_repr_impl, default_richcmp, default_int];
|
||||
|
||||
let pyclass_impls = PyClassImplsBuilder::new(
|
||||
cls,
|
||||
args,
|
||||
methods_type,
|
||||
enum_default_items(cls, variants.iter().map(|v| v.ident), &mut default_methods),
|
||||
)
|
||||
.doc(doc)
|
||||
.impl_all();
|
||||
|
||||
Ok(quote! {
|
||||
const _: () = {
|
||||
|
@ -595,14 +595,17 @@ fn impl_enum_class(
|
|||
|
||||
#pyclass_impls
|
||||
|
||||
#default_items
|
||||
impl #cls {
|
||||
#(#default_methods)*
|
||||
}
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
fn unit_variants_as_items<'a>(
|
||||
fn enum_default_items<'a>(
|
||||
cls: &'a syn::Ident,
|
||||
variant_names: impl IntoIterator<Item = &'a syn::Ident>,
|
||||
unit_variant_names: impl IntoIterator<Item = &'a syn::Ident>,
|
||||
default_items: &mut [syn::ImplItemMethod],
|
||||
) -> TokenStream {
|
||||
let cls_type = syn::parse_quote!(#cls);
|
||||
let variant_to_attribute = |ident: &syn::Ident| ConstSpec {
|
||||
|
@ -613,14 +616,16 @@ fn unit_variants_as_items<'a>(
|
|||
deprecations: Default::default(),
|
||||
},
|
||||
};
|
||||
let py_methods = variant_names
|
||||
let py_methods = unit_variant_names
|
||||
.into_iter()
|
||||
.map(|var| gen_py_const(&cls_type, &variant_to_attribute(var)));
|
||||
|
||||
let slots = gen_default_items(cls, default_items);
|
||||
|
||||
quote! {
|
||||
_pyo3::impl_::pyclass::PyClassItems {
|
||||
methods: &[#(#py_methods),*],
|
||||
slots: &[]
|
||||
slots: &[#(#slots),*]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -918,9 +923,6 @@ impl<'a> PyClassImplsBuilder<'a> {
|
|||
let collector = PyClassImplCollector::<Self>::new();
|
||||
static INTRINSIC_ITEMS: PyClassItems = #default_items;
|
||||
visitor(&INTRINSIC_ITEMS);
|
||||
// This depends on Python implementation detail;
|
||||
// an old slot entry will be overriden by newer ones.
|
||||
visitor(collector.pyclass_default_items());
|
||||
#pymethods_items
|
||||
#pyproto_items
|
||||
}
|
||||
|
|
|
@ -186,24 +186,20 @@ pub fn gen_py_const(cls: &syn::Type, spec: &ConstSpec) -> TokenStream {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gen_default_items(cls: &syn::Ident, method_defs: Vec<TokenStream>) -> TokenStream {
|
||||
pub fn gen_default_items<'a>(
|
||||
cls: &syn::Ident,
|
||||
method_defs: &'a mut [syn::ImplItemMethod],
|
||||
) -> impl Iterator<Item = TokenStream> + 'a {
|
||||
// This function uses a lot of `unwrap()`; since method_defs are provided by us, they should
|
||||
// all succeed.
|
||||
let ty: syn::Type = syn::parse_quote!(#cls);
|
||||
|
||||
let mut method_defs: Vec<_> = method_defs
|
||||
.into_iter()
|
||||
.map(|token| syn::parse2::<syn::ImplItemMethod>(token).unwrap())
|
||||
.collect();
|
||||
|
||||
let mut proto_impls = Vec::new();
|
||||
|
||||
for meth in &mut method_defs {
|
||||
method_defs.into_iter().map(move |meth| {
|
||||
let options = PyFunctionOptions::from_attrs(&mut meth.attrs).unwrap();
|
||||
match pymethod::gen_py_method(&ty, &mut meth.sig, &mut meth.attrs, options).unwrap() {
|
||||
GeneratedPyMethod::Proto(token_stream) => {
|
||||
let attrs = get_cfg_attributes(&meth.attrs);
|
||||
proto_impls.push(quote!(#(#attrs)* #token_stream))
|
||||
quote!(#(#attrs)* #token_stream)
|
||||
}
|
||||
GeneratedPyMethod::SlotTraitImpl(..) => {
|
||||
panic!("SlotFragment methods cannot have default implementation!")
|
||||
|
@ -212,23 +208,7 @@ pub fn gen_default_items(cls: &syn::Ident, method_defs: Vec<TokenStream>) -> Tok
|
|||
panic!("Only protocol methods can have default implementation!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quote! {
|
||||
impl #cls {
|
||||
#(#method_defs)*
|
||||
}
|
||||
impl _pyo3::impl_::pyclass::PyClassDefaultItems<#cls>
|
||||
for _pyo3::impl_::pyclass::PyClassImplCollector<#cls> {
|
||||
fn pyclass_default_items(self) -> &'static _pyo3::impl_::pyclass::PyClassItems {
|
||||
static ITEMS: _pyo3::impl_::pyclass::PyClassItems = _pyo3::impl_::pyclass::PyClassItems {
|
||||
methods: &[],
|
||||
slots: &[#(#proto_impls),*]
|
||||
};
|
||||
&ITEMS
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn impl_py_methods(
|
||||
|
|
|
@ -757,9 +757,6 @@ mod pyproto_traits {
|
|||
#[cfg(feature = "pyproto")]
|
||||
pub use pyproto_traits::*;
|
||||
|
||||
// items that PyO3 implements by default, but can be overidden by the users.
|
||||
items_trait!(PyClassDefaultItems, pyclass_default_items);
|
||||
|
||||
// Protocol slots from #[pymethods] if not using inventory.
|
||||
#[cfg(not(feature = "multiple-pymethods"))]
|
||||
items_trait!(PyMethodsProtocolItems, methods_protocol_items);
|
||||
|
|
Loading…
Reference in New Issue