11use super :: { PyStr , PyType , PyTypeRef } ;
22use crate :: {
33 class:: PyClassImpl ,
4+ function:: PySetterValue ,
45 types:: { Constructor , GetDescriptor , Unconstructible } ,
56 AsObject , Context , Py , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
67} ;
@@ -18,15 +19,23 @@ pub enum MemberKind {
1819 ObjectEx = 16 ,
1920}
2021
22+ pub type MemberSetterFunc = Option < fn ( & VirtualMachine , PyObjectRef , PySetterValue ) -> PyResult < ( ) > > ;
23+
2124pub enum MemberGetter {
2225 Getter ( fn ( & VirtualMachine , PyObjectRef ) -> PyResult ) ,
2326 Offset ( usize ) ,
2427}
2528
29+ pub enum MemberSetter {
30+ Setter ( MemberSetterFunc ) ,
31+ Offset ( usize ) ,
32+ }
33+
2634pub struct MemberDef {
2735 pub name : String ,
2836 pub kind : MemberKind ,
2937 pub getter : MemberGetter ,
38+ pub setter : MemberSetter ,
3039 pub doc : Option < String > ,
3140}
3241
@@ -37,6 +46,21 @@ impl MemberDef {
3746 MemberGetter :: Offset ( offset) => get_slot_from_object ( obj, offset, self , vm) ,
3847 }
3948 }
49+
50+ fn set (
51+ & self ,
52+ obj : PyObjectRef ,
53+ value : PySetterValue < PyObjectRef > ,
54+ vm : & VirtualMachine ,
55+ ) -> PyResult < ( ) > {
56+ match self . setter {
57+ MemberSetter :: Setter ( setter) => match setter {
58+ Some ( setter) => ( setter) ( vm, obj, value) ,
59+ None => Err ( vm. new_attribute_error ( "readonly attribute" . to_string ( ) ) ) ,
60+ } ,
61+ MemberSetter :: Offset ( offset) => set_slot_at_object ( obj, offset, self , value, vm) ,
62+ }
63+ }
4064}
4165
4266impl std:: fmt:: Debug for MemberDef {
@@ -103,6 +127,17 @@ impl MemberDescrObject {
103127 qualname. to_owned ( )
104128 } )
105129 }
130+
131+ #[ pyslot]
132+ fn descr_set (
133+ zelf : PyObjectRef ,
134+ obj : PyObjectRef ,
135+ value : PySetterValue < PyObjectRef > ,
136+ vm : & VirtualMachine ,
137+ ) -> PyResult < ( ) > {
138+ let zelf = Self :: _zelf ( zelf, vm) ?;
139+ zelf. member . set ( obj, value, vm)
140+ }
106141}
107142
108143// PyMember_GetOne
@@ -124,6 +159,24 @@ fn get_slot_from_object(
124159 Ok ( slot)
125160}
126161
162+ // PyMember_SetOne
163+ fn set_slot_at_object (
164+ obj : PyObjectRef ,
165+ offset : usize ,
166+ member : & MemberDef ,
167+ value : PySetterValue ,
168+ _vm : & VirtualMachine ,
169+ ) -> PyResult < ( ) > {
170+ match member. kind {
171+ MemberKind :: ObjectEx => match value {
172+ PySetterValue :: Assign ( v) => obj. set_slot ( offset, Some ( v) ) ,
173+ PySetterValue :: Delete => obj. set_slot ( offset, None ) ,
174+ } ,
175+ }
176+
177+ Ok ( ( ) )
178+ }
179+
127180impl Unconstructible for MemberDescrObject { }
128181
129182impl GetDescriptor for MemberDescrObject {
0 commit comments