@@ -252,10 +252,6 @@ pub enum FnType {
252252 Setter ( SelfType ) ,
253253 /// Represents a regular pymethod
254254 Fn ( SelfType ) ,
255- /// Represents a pymethod annotated with `#[new]`, i.e. the `__new__` dunder.
256- FnNew ,
257- /// Represents a pymethod annotated with both `#[new]` and `#[classmethod]` (in either order)
258- FnNewClass ( Span ) ,
259255 /// Represents a pymethod annotated with `#[classmethod]`, like a `@classmethod`
260256 FnClass ( Span ) ,
261257 /// Represents a pyfunction or a pymethod annotated with `#[staticmethod]`, like a `@staticmethod`
@@ -273,20 +269,14 @@ impl FnType {
273269 | FnType :: Setter ( _)
274270 | FnType :: Fn ( _)
275271 | FnType :: FnClass ( _)
276- | FnType :: FnNewClass ( _)
277272 | FnType :: FnModule ( _) => true ,
278- FnType :: FnNew | FnType :: FnStatic | FnType :: ClassAttribute => false ,
273+ FnType :: FnStatic | FnType :: ClassAttribute => false ,
279274 }
280275 }
281276
282277 pub fn signature_attribute_allowed ( & self ) -> bool {
283278 match self {
284- FnType :: Fn ( _)
285- | FnType :: FnNew
286- | FnType :: FnStatic
287- | FnType :: FnClass ( _)
288- | FnType :: FnNewClass ( _)
289- | FnType :: FnModule ( _) => true ,
279+ FnType :: Fn ( _) | FnType :: FnStatic | FnType :: FnClass ( _) | FnType :: FnModule ( _) => true ,
290280 // Setter, Getter and ClassAttribute all have fixed signatures (either take 0 or 1
291281 // arguments) so cannot have a `signature = (...)` attribute.
292282 FnType :: Getter ( _) | FnType :: Setter ( _) | FnType :: ClassAttribute => false ,
@@ -312,7 +302,7 @@ impl FnType {
312302 syn:: Token ![ , ] ( Span :: call_site ( ) ) . to_tokens ( & mut receiver) ;
313303 Some ( receiver)
314304 }
315- FnType :: FnClass ( span) | FnType :: FnNewClass ( span ) => {
305+ FnType :: FnClass ( span) => {
316306 let py = syn:: Ident :: new ( "py" , Span :: call_site ( ) ) ;
317307 let slf: Ident = syn:: Ident :: new ( "_slf" , Span :: call_site ( ) ) ;
318308 let pyo3_path = pyo3_path. to_tokens_spanned ( * span) ;
@@ -338,7 +328,7 @@ impl FnType {
338328 } ;
339329 Some ( quote ! { unsafe { #ret } , } )
340330 }
341- FnType :: FnNew | FnType :: FnStatic | FnType :: ClassAttribute => None ,
331+ FnType :: FnStatic | FnType :: ClassAttribute => None ,
342332 }
343333 }
344334}
@@ -424,12 +414,11 @@ impl SelfType {
424414}
425415
426416/// Determines which CPython calling convention a given FnSpec uses.
427- #[ derive( Clone , Debug ) ]
417+ #[ derive( Clone , Debug , Copy ) ]
428418pub enum CallingConvention {
429419 Noargs , // METH_NOARGS
430420 Varargs , // METH_VARARGS | METH_KEYWORDS
431421 Fastcall , // METH_FASTCALL | METH_KEYWORDS (not compatible with `abi3` feature before 3.10)
432- TpNew , // special convention for tp_new
433422}
434423
435424impl CallingConvention {
@@ -461,7 +450,6 @@ pub struct FnSpec<'a> {
461450 // r# can be removed by syn::ext::IdentExt::unraw()
462451 pub python_name : syn:: Ident ,
463452 pub signature : FunctionSignature < ' a > ,
464- pub convention : CallingConvention ,
465453 pub text_signature : Option < TextSignatureAttribute > ,
466454 pub asyncness : Option < syn:: Token ![ async ] > ,
467455 pub unsafety : Option < syn:: Token ![ unsafe ] > ,
@@ -533,16 +521,9 @@ impl<'a> FnSpec<'a> {
533521 FunctionSignature :: from_arguments ( arguments)
534522 } ;
535523
536- let convention = if matches ! ( fn_type, FnType :: FnNew | FnType :: FnNewClass ( _) ) {
537- CallingConvention :: TpNew
538- } else {
539- CallingConvention :: from_signature ( & signature)
540- } ;
541-
542524 Ok ( FnSpec {
543525 tp : fn_type,
544526 name,
545- convention,
546527 python_name,
547528 signature,
548529 text_signature,
@@ -600,12 +581,12 @@ impl<'a> FnSpec<'a> {
600581 [ MethodTypeAttribute :: ClassAttribute ( _) ] => FnType :: ClassAttribute ,
601582 [ MethodTypeAttribute :: New ( _) ] => {
602583 set_name_to_new ( ) ?;
603- FnType :: FnNew
584+ FnType :: FnStatic
604585 }
605586 [ MethodTypeAttribute :: New ( _) , MethodTypeAttribute :: ClassMethod ( span) ]
606587 | [ MethodTypeAttribute :: ClassMethod ( span) , MethodTypeAttribute :: New ( _) ] => {
607588 set_name_to_new ( ) ?;
608- FnType :: FnNewClass ( * span)
589+ FnType :: FnClass ( * span)
609590 }
610591 [ MethodTypeAttribute :: ClassMethod ( _) ] => {
611592 // Add a helpful hint if the classmethod doesn't look like a classmethod
@@ -677,6 +658,7 @@ impl<'a> FnSpec<'a> {
677658 & self ,
678659 ident : & proc_macro2:: Ident ,
679660 cls : Option < & syn:: Type > ,
661+ convention : CallingConvention ,
680662 ctx : & Ctx ,
681663 ) -> Result < TokenStream > {
682664 let Ctx {
@@ -799,7 +781,7 @@ impl<'a> FnSpec<'a> {
799781
800782 let warnings = self . warnings . build_py_warning ( ctx) ;
801783
802- Ok ( match self . convention {
784+ Ok ( match convention {
803785 CallingConvention :: Noargs => {
804786 let mut holders = Holders :: new ( ) ;
805787 let args = self
@@ -872,52 +854,31 @@ impl<'a> FnSpec<'a> {
872854 }
873855 }
874856 }
875- CallingConvention :: TpNew => {
876- let mut holders = Holders :: new ( ) ;
877- let ( arg_convert, args) = impl_arg_params ( self , cls, false , & mut holders, ctx) ;
878- let self_arg = self
879- . tp
880- . self_arg ( cls, ExtractErrorMode :: Raise , & mut holders, ctx) ;
881- let call = quote_spanned ! { * output_span=> #rust_name( #self_arg #( #args) , * ) } ;
882- let init_holders = holders. init_holders ( ctx) ;
883- quote ! {
884- unsafe fn #ident(
885- py: #pyo3_path:: Python <' _>,
886- _slf: * mut #pyo3_path:: ffi:: PyTypeObject ,
887- _args: * mut #pyo3_path:: ffi:: PyObject ,
888- _kwargs: * mut #pyo3_path:: ffi:: PyObject
889- ) -> #pyo3_path:: PyResult <* mut #pyo3_path:: ffi:: PyObject > {
890- use #pyo3_path:: impl_:: callback:: IntoPyCallbackOutput ;
891- let function = #rust_name; // Shadow the function name to avoid #3017
892- #arg_convert
893- #init_holders
894- #warnings
895- let result = #call;
896- let initializer: #pyo3_path:: PyClassInitializer :: <#cls> = result. convert( py) ?;
897- #pyo3_path:: impl_:: pymethods:: tp_new_impl( py, initializer, _slf)
898- }
899- }
900- }
901857 } )
902858 }
903859
904860 /// Return a `PyMethodDef` constructor for this function, matching the selected
905861 /// calling convention.
906- pub fn get_methoddef ( & self , wrapper : impl ToTokens , doc : & PythonDoc , ctx : & Ctx ) -> TokenStream {
862+ pub fn get_methoddef (
863+ & self ,
864+ wrapper : impl ToTokens ,
865+ doc : & PythonDoc ,
866+ convention : CallingConvention ,
867+ ctx : & Ctx ,
868+ ) -> TokenStream {
907869 let Ctx { pyo3_path, .. } = ctx;
908870 let python_name = self . null_terminated_python_name ( ) ;
909871 let flags = match self . tp {
910872 FnType :: FnClass ( _) => quote ! { . flags( #pyo3_path:: ffi:: METH_CLASS ) } ,
911873 FnType :: FnStatic => quote ! { . flags( #pyo3_path:: ffi:: METH_STATIC ) } ,
912874 _ => quote ! { } ,
913875 } ;
914- let trampoline = match self . convention {
876+ let trampoline = match convention {
915877 CallingConvention :: Noargs => Ident :: new ( "noargs" , Span :: call_site ( ) ) ,
916878 CallingConvention :: Fastcall => {
917879 Ident :: new ( "fastcall_cfunction_with_keywords" , Span :: call_site ( ) )
918880 }
919881 CallingConvention :: Varargs => Ident :: new ( "cfunction_with_keywords" , Span :: call_site ( ) ) ,
920- CallingConvention :: TpNew => unreachable ! ( "tp_new cannot get a methoddef" ) ,
921882 } ;
922883 quote ! {
923884 #pyo3_path:: impl_:: pymethods:: PyMethodDef :: #trampoline(
@@ -944,8 +905,8 @@ impl<'a> FnSpec<'a> {
944905 FnType :: Getter ( _) | FnType :: Setter ( _) | FnType :: ClassAttribute => return None ,
945906 FnType :: Fn ( _) => Some ( "self" ) ,
946907 FnType :: FnModule ( _) => Some ( "module" ) ,
947- FnType :: FnClass ( _) | FnType :: FnNewClass ( _ ) => Some ( "cls" ) ,
948- FnType :: FnStatic | FnType :: FnNew => None ,
908+ FnType :: FnClass ( _) => Some ( "cls" ) ,
909+ FnType :: FnStatic => None ,
949910 } ;
950911
951912 match self . text_signature . as_ref ( ) . map ( |attr| & attr. value ) {
0 commit comments