44use super :: PyType ;
55use crate :: {
66 class:: PyClassImpl ,
7- convert:: ToPyResult ,
8- function:: { OwnedParam , RefParam } ,
9- object:: PyThreadingConstraint ,
7+ function:: { IntoPyGetterFunc , IntoPySetterFunc , PyGetterFunc , PySetterFunc , PySetterValue } ,
108 types:: { Constructor , GetDescriptor , Unconstructible } ,
119 AsObject , Context , Py , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject , VirtualMachine ,
1210} ;
1311
14- pub type PyGetterFunc = Box < py_dyn_fn ! ( dyn Fn ( & VirtualMachine , PyObjectRef ) -> PyResult ) > ;
15- pub type PySetterFunc =
16- Box < py_dyn_fn ! ( dyn Fn ( & VirtualMachine , PyObjectRef , PyObjectRef ) -> PyResult <( ) >) > ;
17-
18- pub trait IntoPyGetterFunc < T > : PyThreadingConstraint + Sized + ' static {
19- fn get ( & self , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult ;
20- fn into_getter ( self ) -> PyGetterFunc {
21- Box :: new ( move |vm, obj| self . get ( obj, vm) )
22- }
23- }
24-
25- impl < F , T , R > IntoPyGetterFunc < ( OwnedParam < T > , R , VirtualMachine ) > for F
26- where
27- F : Fn ( T , & VirtualMachine ) -> R + ' static + Send + Sync ,
28- T : TryFromObject ,
29- R : ToPyResult ,
30- {
31- fn get ( & self , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
32- let obj = T :: try_from_object ( vm, obj) ?;
33- ( self ) ( obj, vm) . to_pyresult ( vm)
34- }
35- }
36-
37- impl < F , S , R > IntoPyGetterFunc < ( RefParam < S > , R , VirtualMachine ) > for F
38- where
39- F : Fn ( & S , & VirtualMachine ) -> R + ' static + Send + Sync ,
40- S : PyPayload ,
41- R : ToPyResult ,
42- {
43- fn get ( & self , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
44- let zelf = PyRef :: < S > :: try_from_object ( vm, obj) ?;
45- ( self ) ( & zelf, vm) . to_pyresult ( vm)
46- }
47- }
48-
49- impl < F , T , R > IntoPyGetterFunc < ( OwnedParam < T > , R ) > for F
50- where
51- F : Fn ( T ) -> R + ' static + Send + Sync ,
52- T : TryFromObject ,
53- R : ToPyResult ,
54- {
55- fn get ( & self , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
56- let obj = T :: try_from_object ( vm, obj) ?;
57- ( self ) ( obj) . to_pyresult ( vm)
58- }
59- }
60-
61- impl < F , S , R > IntoPyGetterFunc < ( RefParam < S > , R ) > for F
62- where
63- F : Fn ( & S ) -> R + ' static + Send + Sync ,
64- S : PyPayload ,
65- R : ToPyResult ,
66- {
67- fn get ( & self , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
68- let zelf = PyRef :: < S > :: try_from_object ( vm, obj) ?;
69- ( self ) ( & zelf) . to_pyresult ( vm)
70- }
71- }
72-
73- pub trait IntoPyNoResult {
74- fn into_noresult ( self ) -> PyResult < ( ) > ;
75- }
76-
77- impl IntoPyNoResult for ( ) {
78- #[ inline]
79- fn into_noresult ( self ) -> PyResult < ( ) > {
80- Ok ( ( ) )
81- }
82- }
83-
84- impl IntoPyNoResult for PyResult < ( ) > {
85- #[ inline]
86- fn into_noresult ( self ) -> PyResult < ( ) > {
87- self
88- }
89- }
90-
91- pub trait IntoPySetterFunc < T > : PyThreadingConstraint + Sized + ' static {
92- fn set ( & self , obj : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > ;
93- fn into_setter ( self ) -> PySetterFunc {
94- Box :: new ( move |vm, obj, value| self . set ( obj, value, vm) )
95- }
96- }
97-
98- impl < F , T , V , R > IntoPySetterFunc < ( OwnedParam < T > , V , R , VirtualMachine ) > for F
99- where
100- F : Fn ( T , V , & VirtualMachine ) -> R + ' static + Send + Sync ,
101- T : TryFromObject ,
102- V : TryFromObject ,
103- R : IntoPyNoResult ,
104- {
105- fn set ( & self , obj : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
106- let obj = T :: try_from_object ( vm, obj) ?;
107- let value = V :: try_from_object ( vm, value) ?;
108- ( self ) ( obj, value, vm) . into_noresult ( )
109- }
110- }
111-
112- impl < F , S , V , R > IntoPySetterFunc < ( RefParam < S > , V , R , VirtualMachine ) > for F
113- where
114- F : Fn ( & S , V , & VirtualMachine ) -> R + ' static + Send + Sync ,
115- S : PyPayload ,
116- V : TryFromObject ,
117- R : IntoPyNoResult ,
118- {
119- fn set ( & self , obj : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
120- let zelf = PyRef :: < S > :: try_from_object ( vm, obj) ?;
121- let value = V :: try_from_object ( vm, value) ?;
122- ( self ) ( & zelf, value, vm) . into_noresult ( )
123- }
124- }
125-
126- impl < F , T , V , R > IntoPySetterFunc < ( OwnedParam < T > , V , R ) > for F
127- where
128- F : Fn ( T , V ) -> R + ' static + Send + Sync ,
129- T : TryFromObject ,
130- V : TryFromObject ,
131- R : IntoPyNoResult ,
132- {
133- fn set ( & self , obj : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
134- let obj = T :: try_from_object ( vm, obj) ?;
135- let value = V :: try_from_object ( vm, value) ?;
136- ( self ) ( obj, value) . into_noresult ( )
137- }
138- }
139-
140- impl < F , S , V , R > IntoPySetterFunc < ( RefParam < S > , V , R ) > for F
141- where
142- F : Fn ( & S , V ) -> R + ' static + Send + Sync ,
143- S : PyPayload ,
144- V : TryFromObject ,
145- R : IntoPyNoResult ,
146- {
147- fn set ( & self , obj : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
148- let zelf = PyRef :: < S > :: try_from_object ( vm, obj) ?;
149- let value = V :: try_from_object ( vm, value) ?;
150- ( self ) ( & zelf, value) . into_noresult ( )
151- }
152- }
153-
15412#[ pyclass( module = false , name = "getset_descriptor" ) ]
15513pub struct PyGetSet {
15614 name : String ,
@@ -244,12 +102,12 @@ impl PyGetSet {
244102 fn descr_set (
245103 zelf : PyObjectRef ,
246104 obj : PyObjectRef ,
247- value : Option < PyObjectRef > ,
105+ value : PySetterValue < PyObjectRef > ,
248106 vm : & VirtualMachine ,
249107 ) -> PyResult < ( ) > {
250108 let zelf = PyRef :: < Self > :: try_from_object ( vm, zelf) ?;
251109 if let Some ( ref f) = zelf. setter {
252- f ( vm, obj, value. unwrap_or_else ( || vm . ctx . none ( ) ) )
110+ f ( vm, obj, value)
253111 } else {
254112 Err ( vm. new_attribute_error ( format ! (
255113 "attribute '{}' of '{}' objects is not writable" ,
@@ -265,11 +123,11 @@ impl PyGetSet {
265123 value : PyObjectRef ,
266124 vm : & VirtualMachine ,
267125 ) -> PyResult < ( ) > {
268- Self :: descr_set ( zelf, obj, Some ( value) , vm)
126+ Self :: descr_set ( zelf, obj, PySetterValue :: Assign ( value) , vm)
269127 }
270128 #[ pymethod]
271129 fn __delete__ ( zelf : PyObjectRef , obj : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
272- Self :: descr_set ( zelf, obj, None , vm)
130+ Self :: descr_set ( zelf, obj, PySetterValue :: Delete , vm)
273131 }
274132
275133 #[ pyproperty( magic) ]
0 commit comments