@@ -63,6 +63,7 @@ impl FromStr for AttrName {
6363
6464#[ derive( Default ) ]
6565struct ImplContext {
66+ is_trait : bool ,
6667 attribute_items : ItemNursery ,
6768 method_items : MethodNursery ,
6869 getset_items : GetSetNursery ,
@@ -232,7 +233,10 @@ pub(crate) fn impl_pyclass_impl(attr: PunctuatedNestedMeta, item: Item) -> Resul
232233 }
233234 }
234235 Item :: Trait ( mut trai) => {
235- let mut context = ImplContext :: default ( ) ;
236+ let mut context = ImplContext {
237+ is_trait : true ,
238+ ..Default :: default ( )
239+ } ;
236240 let mut has_extend_slots = false ;
237241 for item in & trai. items {
238242 let has = match item {
@@ -892,6 +896,23 @@ where
892896 let item_meta = MethodItemMeta :: from_attr ( ident. clone ( ) , & item_attr) ?;
893897
894898 let py_name = item_meta. method_name ( ) ?;
899+
900+ // Disallow __new__ and __init__ as pymethod in impl blocks (not in traits)
901+ if !args. context . is_trait {
902+ if py_name == "__new__" {
903+ return Err ( syn:: Error :: new (
904+ ident. span ( ) ,
905+ "#[pymethod] cannot define '__new__'. Use #[pyclass(with(Constructor))] instead." ,
906+ ) ) ;
907+ }
908+ if py_name == "__init__" {
909+ return Err ( syn:: Error :: new (
910+ ident. span ( ) ,
911+ "#[pymethod] cannot define '__init__'. Use #[pyclass(with(Initializer))] instead." ,
912+ ) ) ;
913+ }
914+ }
915+
895916 let raw = item_meta. raw ( ) ?;
896917 let sig_doc = text_signature ( func. sig ( ) , & py_name) ;
897918
0 commit comments