diff --git a/crates/derive-impl/src/pyclass.rs b/crates/derive-impl/src/pyclass.rs index 84559e3574e..86b038f2082 100644 --- a/crates/derive-impl/src/pyclass.rs +++ b/crates/derive-impl/src/pyclass.rs @@ -579,14 +579,30 @@ pub(crate) fn impl_pyexception_impl(attr: PunctuatedNestedMeta, item: Item) -> R return Ok(item.into_token_stream()); }; - if !attr.is_empty() { - return Err(syn::Error::new_spanned( - &attr[0], - "#[pyexception] impl doesn't allow attrs. Use #[pyclass] instead.", - )); + // Check if with(Constructor) is specified. If Constructor trait is used, don't generate slot_new + let mut has_slot_new = false; + + let mut extra_attrs = Vec::new(); + for nested in &attr { + if let NestedMeta::Meta(Meta::List(MetaList { path, nested, .. })) = nested { + if path.is_ident("with") { + // Check if Constructor is in the list + for meta in nested { + if let NestedMeta::Meta(Meta::Path(p)) = meta + && p.is_ident("Constructor") + { + has_slot_new = true; + } + } + } + extra_attrs.push(NestedMeta::Meta(Meta::List(MetaList { + path: path.clone(), + paren_token: Default::default(), + nested: nested.clone(), + }))); + } } - let mut has_slot_new = false; let mut has_slot_init = false; let syn::ItemImpl { generics, @@ -611,6 +627,8 @@ pub(crate) fn impl_pyexception_impl(attr: PunctuatedNestedMeta, item: Item) -> R } } + // TODO: slot_new, slot_init must be Constructor or Initializer later + let slot_new = if has_slot_new { quote!() } else { @@ -646,8 +664,15 @@ pub(crate) fn impl_pyexception_impl(attr: PunctuatedNestedMeta, item: Item) -> R } } }; + + let extra_attrs_tokens = if extra_attrs.is_empty() { + quote!() + } else { + quote!(, #(#extra_attrs),*) + }; + Ok(quote! { - #[pyclass(flags(BASETYPE, HAS_DICT))] + #[pyclass(flags(BASETYPE, HAS_DICT) #extra_attrs_tokens)] impl #generics #self_ty { #(#items)*