| 745 | } |
| 746 | |
| 747 | pub(crate) fn impl_pyexception_impl(attr: PunctuatedNestedMeta, item: Item) -> Result<TokenStream> { |
| 748 | let Item::Impl(imp) = item else { |
| 749 | return Ok(item.into_token_stream()); |
| 750 | }; |
| 751 | |
| 752 | // Check if with(Constructor) is specified. If Constructor trait is used, don't generate slot_new |
| 753 | let mut extra_attrs = Vec::new(); |
| 754 | let mut with_items = vec![]; |
| 755 | for nested in &attr { |
| 756 | if let NestedMeta::Meta(Meta::List(MetaList { path, nested, .. })) = nested { |
| 757 | // If we already found the constructor trait, no need to keep looking for it |
| 758 | if path.is_ident("with") { |
| 759 | for meta in nested { |
| 760 | with_items.push(meta.get_ident().expect("with() has non-ident item").clone()); |
| 761 | } |
| 762 | continue; |
| 763 | } |
| 764 | extra_attrs.push(NestedMeta::Meta(Meta::List(MetaList { |
| 765 | path: path.clone(), |
| 766 | paren_token: Default::default(), |
| 767 | nested: nested.clone(), |
| 768 | }))); |
| 769 | } |
| 770 | } |
| 771 | |
| 772 | let with_contains = |with_items: &[Ident], s: &str| { |
| 773 | // Check if Constructor is in the list |
| 774 | with_items.iter().any(|ident| ident == s) |
| 775 | }; |
| 776 | |
| 777 | let syn::ItemImpl { |
| 778 | generics, |
| 779 | self_ty, |
| 780 | items, |
| 781 | .. |
| 782 | } = &imp; |
| 783 | |
| 784 | let slot_new = if with_contains(&with_items, "Constructor") { |
| 785 | quote!() |
| 786 | } else { |
| 787 | with_items.push(Ident::new("Constructor", Span::call_site())); |
| 788 | quote! { |
| 789 | impl ::rustpython_vm::types::Constructor for #self_ty { |
| 790 | type Args = ::rustpython_vm::function::FuncArgs; |
| 791 | |
| 792 | fn slot_new( |
| 793 | cls: ::rustpython_vm::builtins::PyTypeRef, |
| 794 | args: ::rustpython_vm::function::FuncArgs, |
| 795 | vm: &::rustpython_vm::VirtualMachine, |
| 796 | ) -> ::rustpython_vm::PyResult { |
| 797 | <Self as ::rustpython_vm::class::PyClassDef>::Base::slot_new(cls, args, vm) |
| 798 | } |
| 799 | fn py_new( |
| 800 | _cls: &::rustpython_vm::Py<::rustpython_vm::builtins::PyType>, |
| 801 | _args: Self::Args, |
| 802 | _vm: &::rustpython_vm::VirtualMachine |
| 803 | ) -> ::rustpython_vm::PyResult<Self> { |
| 804 | unreachable!("slot_new is defined") |