1- use super :: { PyStr , PyType , PyTypeRef } ;
1+ use super :: { PyBoundMethod , PyStr , PyType , PyTypeRef } ;
22use crate :: {
33 builtins:: builtinfunc:: PyBuiltinMethod ,
44 class:: PyClassImpl ,
5+ common:: lock:: PyMutex ,
56 function:: { FuncArgs , IntoPyNativeFunc } ,
67 types:: { Callable , Constructor , GetDescriptor , Initializer } ,
7- Context , Py , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
8+ AsObject , Context , Py , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
89} ;
910
1011#[ pyclass( module = false , name = "staticmethod" ) ]
11- #[ derive( Clone , Debug ) ]
12+ #[ derive( Debug ) ]
1213pub struct PyStaticMethod {
13- pub callable : PyObjectRef ,
14+ pub callable : PyMutex < PyObjectRef > ,
1415}
1516
1617impl PyPayload for PyStaticMethod {
@@ -22,18 +23,25 @@ impl PyPayload for PyStaticMethod {
2223impl GetDescriptor for PyStaticMethod {
2324 fn descr_get (
2425 zelf : PyObjectRef ,
25- _obj : Option < PyObjectRef > ,
26- _cls : Option < PyObjectRef > ,
26+ obj : Option < PyObjectRef > ,
27+ cls : Option < PyObjectRef > ,
2728 vm : & VirtualMachine ,
2829 ) -> PyResult {
29- let zelf = Self :: _zelf ( zelf, vm) ?;
30- Ok ( zelf. callable . clone ( ) )
30+ let ( zelf, _obj) = Self :: _unwrap ( zelf, obj, vm) ?;
31+ let cls = cls. unwrap_or_else ( || _obj. class ( ) . clone ( ) . into ( ) ) ;
32+ let call_descr_get: PyResult < PyObjectRef > = zelf. callable . lock ( ) . get_attr ( "__get__" , vm) ;
33+ match call_descr_get {
34+ Err ( _) => Ok ( PyBoundMethod :: new_ref ( cls, zelf. callable . lock ( ) . clone ( ) , & vm. ctx ) . into ( ) ) ,
35+ Ok ( call_descr_get) => vm. invoke ( & call_descr_get, ( cls. clone ( ) , cls) ) ,
36+ }
3137 }
3238}
3339
3440impl From < PyObjectRef > for PyStaticMethod {
3541 fn from ( callable : PyObjectRef ) -> Self {
36- Self { callable }
42+ Self {
43+ callable : PyMutex :: new ( callable) ,
44+ }
3745 }
3846}
3947
@@ -43,7 +51,10 @@ impl Constructor for PyStaticMethod {
4351 fn py_new ( cls : PyTypeRef , callable : Self :: Args , vm : & VirtualMachine ) -> PyResult {
4452 let doc = callable. get_attr ( "__doc__" , vm) ;
4553
46- let result = PyStaticMethod { callable } . into_ref_with_type ( vm, cls) ?;
54+ let result = PyStaticMethod {
55+ callable : PyMutex :: new ( callable) ,
56+ }
57+ . into_ref_with_type ( vm, cls) ?;
4758 let obj = PyObjectRef :: from ( result) ;
4859
4960 if let Ok ( doc) = doc {
@@ -54,6 +65,18 @@ impl Constructor for PyStaticMethod {
5465 }
5566}
5667
68+ impl PyStaticMethod {
69+ pub fn new_ref ( callable : PyObjectRef , ctx : & Context ) -> PyRef < Self > {
70+ PyRef :: new_ref (
71+ Self {
72+ callable : PyMutex :: new ( callable) ,
73+ } ,
74+ ctx. types . staticmethod_type . to_owned ( ) ,
75+ None ,
76+ )
77+ }
78+ }
79+
5780impl PyStaticMethod {
5881 pub fn new_builtin_ref < F , FKind > (
5982 name : impl Into < PyStr > ,
@@ -66,7 +89,9 @@ impl PyStaticMethod {
6689 {
6790 let callable = PyBuiltinMethod :: new_ref ( name, class, f, ctx) . into ( ) ;
6891 PyRef :: new_ref (
69- Self { callable } ,
92+ Self {
93+ callable : PyMutex :: new ( callable) ,
94+ } ,
7095 ctx. types . staticmethod_type . to_owned ( ) ,
7196 None ,
7297 )
@@ -76,49 +101,47 @@ impl PyStaticMethod {
76101impl Initializer for PyStaticMethod {
77102 type Args = PyObjectRef ;
78103
79- fn init ( _zelf : PyRef < Self > , _func : Self :: Args , _vm : & VirtualMachine ) -> PyResult < ( ) > {
104+ fn init ( zelf : PyRef < Self > , callable : Self :: Args , _vm : & VirtualMachine ) -> PyResult < ( ) > {
105+ * zelf. callable . lock ( ) = callable;
80106 Ok ( ( ) )
81107 }
82108}
83109
84- #[ pyclass(
85- with( Callable , GetDescriptor , Constructor , Initializer ) ,
86- flags( BASETYPE , HAS_DICT )
87- ) ]
110+ #[ pyclass( with( Callable , Constructor , Initializer ) , flags( BASETYPE , HAS_DICT ) ) ]
88111impl PyStaticMethod {
89112 #[ pyproperty( magic) ]
90113 fn func ( & self ) -> PyObjectRef {
91- self . callable . clone ( )
114+ self . callable . lock ( ) . clone ( )
92115 }
93116
94117 #[ pyproperty( magic) ]
95118 fn wrapped ( & self ) -> PyObjectRef {
96- self . callable . clone ( )
119+ self . callable . lock ( ) . clone ( )
97120 }
98121
99122 #[ pyproperty( magic) ]
100123 fn module ( & self , vm : & VirtualMachine ) -> PyResult {
101- self . callable . get_attr ( "__module__" , vm)
124+ self . callable . lock ( ) . get_attr ( "__module__" , vm)
102125 }
103126
104127 #[ pyproperty( magic) ]
105128 fn qualname ( & self , vm : & VirtualMachine ) -> PyResult {
106- self . callable . get_attr ( "__qualname__" , vm)
129+ self . callable . lock ( ) . get_attr ( "__qualname__" , vm)
107130 }
108131
109132 #[ pyproperty( magic) ]
110133 fn name ( & self , vm : & VirtualMachine ) -> PyResult {
111- self . callable . get_attr ( "__name__" , vm)
134+ self . callable . lock ( ) . get_attr ( "__name__" , vm)
112135 }
113136
114137 #[ pyproperty( magic) ]
115138 fn annotations ( & self , vm : & VirtualMachine ) -> PyResult {
116- self . callable . get_attr ( "__annotations__" , vm)
139+ self . callable . lock ( ) . get_attr ( "__annotations__" , vm)
117140 }
118141
119142 #[ pymethod( magic) ]
120143 fn repr ( & self , vm : & VirtualMachine ) -> Option < String > {
121- let callable = self . callable . repr ( vm) . unwrap ( ) ;
144+ let callable = self . callable . lock ( ) . repr ( vm) . unwrap ( ) ;
122145 let class = Self :: class ( vm) ;
123146
124147 match (
@@ -138,15 +161,17 @@ impl PyStaticMethod {
138161
139162 #[ pyproperty( magic) ]
140163 fn isabstractmethod ( & self , vm : & VirtualMachine ) -> PyObjectRef {
141- match vm. get_attribute_opt ( self . callable . clone ( ) , "__isabstractmethod__" ) {
164+ match vm. get_attribute_opt ( self . callable . lock ( ) . clone ( ) , "__isabstractmethod__" ) {
142165 Ok ( Some ( is_abstract) ) => is_abstract,
143166 _ => vm. ctx . new_bool ( false ) . into ( ) ,
144167 }
145168 }
146169
147170 #[ pyproperty( magic, setter) ]
148171 fn set_isabstractmethod ( & self , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
149- self . callable . set_attr ( "__isabstractmethod__" , value, vm) ?;
172+ self . callable
173+ . lock ( )
174+ . set_attr ( "__isabstractmethod__" , value, vm) ?;
150175 Ok ( ( ) )
151176 }
152177}
@@ -155,7 +180,7 @@ impl Callable for PyStaticMethod {
155180 type Args = FuncArgs ;
156181 #[ inline]
157182 fn call ( zelf : & crate :: Py < Self > , args : FuncArgs , vm : & VirtualMachine ) -> PyResult {
158- vm. invoke ( & zelf. callable , args)
183+ vm. invoke ( & zelf. callable . lock ( ) . clone ( ) , args)
159184 }
160185}
161186
0 commit comments