@@ -54,18 +54,10 @@ unsafe impl Traverse for PyFunction {
5454}
5555
5656impl PyFunction {
57- #[ allow( clippy:: too_many_arguments) ]
5857 #[ inline]
5958 pub ( crate ) fn new (
6059 code : PyRef < PyCode > ,
6160 globals : PyDictRef ,
62- closure : Option < PyRef < PyTuple < PyCellRef > > > ,
63- defaults : Option < PyTupleRef > ,
64- kw_only_defaults : Option < PyDictRef > ,
65- qualname : PyStrRef ,
66- type_params : PyTupleRef ,
67- annotations : PyDictRef ,
68- doc : PyObjectRef ,
6961 vm : & VirtualMachine ,
7062 ) -> PyResult < Self > {
7163 let name = PyMutex :: new ( code. obj_name . to_owned ( ) ) ;
@@ -79,18 +71,21 @@ impl PyFunction {
7971 }
8072 } ) ;
8173
74+ // CPython 3.13 style: Use minimal attributes, others will be set via SET_FUNCTION_ATTRIBUTE
75+ let qualname = vm. ctx . new_str ( code. qualname . as_str ( ) ) ;
76+
8277 let func = Self {
83- code,
78+ code : code . clone ( ) ,
8479 globals,
8580 builtins,
86- closure,
87- defaults_and_kwdefaults : PyMutex :: new ( ( defaults , kw_only_defaults ) ) ,
81+ closure : None , // will be set by SET_FUNCTION_ATTRIBUTE
82+ defaults_and_kwdefaults : PyMutex :: new ( ( None , None ) ) , // will be set by SET_FUNCTION_ATTRIBUTE
8883 name,
8984 qualname : PyMutex :: new ( qualname) ,
90- type_params : PyMutex :: new ( type_params ) ,
91- annotations : PyMutex :: new ( annotations ) ,
85+ type_params : PyMutex :: new ( vm . ctx . empty_tuple . clone ( ) ) , // will be set by SET_FUNCTION_ATTRIBUTE
86+ annotations : PyMutex :: new ( vm . ctx . new_dict ( ) ) , // will be set by SET_FUNCTION_ATTRIBUTE
9287 module : PyMutex :: new ( module) ,
93- doc : PyMutex :: new ( doc ) ,
88+ doc : PyMutex :: new ( vm . ctx . none ( ) ) , // will be set by SET_FUNCTION_ATTRIBUTE
9489 #[ cfg( feature = "jit" ) ]
9590 jitted_code : OnceCell :: new ( ) ,
9691 } ;
@@ -682,34 +677,25 @@ impl Constructor for PyFunction {
682677 None
683678 } ;
684679
685- // Get function name - use provided name or default to code object name
686- let name = args
687- . name
688- . into_option ( )
689- . unwrap_or_else ( || PyStr :: from ( args. code . obj_name . as_str ( ) ) . into_ref ( & vm. ctx ) ) ;
690-
691- // Get qualname - for now just use the name
692- let qualname = name. clone ( ) ;
693-
694- // Create empty type_params and annotations
695- let type_params = vm. ctx . new_tuple ( vec ! [ ] ) ;
696- let annotations = vm. ctx . new_dict ( ) ;
697-
698- // Get doc from code object - for now just use None
699- let doc = vm. ctx . none ( ) ;
700-
701- let func = Self :: new (
702- args. code ,
703- args. globals ,
704- closure,
705- args. defaults . into_option ( ) ,
706- args. kwdefaults . into_option ( ) ,
707- qualname,
708- type_params,
709- annotations,
710- doc,
711- vm,
712- ) ?;
680+ // CPython 3.13 style: Create minimal function, set attributes separately
681+ let mut func = Self :: new ( args. code . clone ( ) , args. globals . clone ( ) , vm) ?;
682+
683+ // Set function name if provided
684+ if let Some ( name) = args. name . into_option ( ) {
685+ * func. name . lock ( ) = name. clone ( ) ;
686+ // Also update qualname to match the name
687+ * func. qualname . lock ( ) = name;
688+ }
689+ // Now set additional attributes directly
690+ if let Some ( closure_tuple) = closure {
691+ func. closure = Some ( closure_tuple) ;
692+ }
693+ if let Some ( defaults) = args. defaults . into_option ( ) {
694+ func. defaults_and_kwdefaults . lock ( ) . 0 = Some ( defaults) ;
695+ }
696+ if let Some ( kwdefaults) = args. kwdefaults . into_option ( ) {
697+ func. defaults_and_kwdefaults . lock ( ) . 1 = Some ( kwdefaults) ;
698+ }
713699
714700 func. into_ref_with_type ( vm, cls) . map ( Into :: into)
715701 }
0 commit comments