1- use crate :: builtins:: { PyBytes , PyFloat , PyInt , PyNone , PyStr } ;
2- use crate :: { PyObjectRef , PyResult , TryFromObject , VirtualMachine } ;
1+ use crate :: builtins:: { PyBytes , PyFloat , PyInt , PyNone , PyStr , PyTypeRef } ;
2+ use crate :: { AsObject , Py , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject , VirtualMachine } ;
33use crossbeam_utils:: atomic:: AtomicCell ;
44use num_traits:: ToPrimitive ;
55use rustpython_common:: lock:: PyRwLock ;
66use std:: fmt:: Debug ;
7+ use crate :: function:: { Either , OptionalArg } ;
8+ use crate :: stdlib:: ctypes:: _ctypes:: new_simple_type;
9+ use crate :: builtins:: PyType ;
710
811#[ allow( dead_code) ]
912fn set_primitive ( _type_ : & str , value : & PyObjectRef , vm : & VirtualMachine ) -> PyResult {
@@ -128,11 +131,24 @@ pub struct PyCData {
128131#[ pyclass]
129132impl PyCData { }
130133
134+ #[ pyclass( module = "_ctypes" , name = "PyCSimpleType" , base = "PyType" ) ]
135+ pub struct PySimpleMeta { }
136+
137+ #[ pyclass( flags( BASETYPE ) ) ]
138+ impl PySimpleMeta {
139+ #[ pymethod]
140+ fn new ( cls : PyTypeRef , _: OptionalArg , vm : & VirtualMachine ) -> PyResult {
141+ Ok ( PyObjectRef :: from ( new_simple_type ( Either :: B ( & cls) , vm) ?
142+ . into_ref_with_type ( vm, cls) ?
143+ . clone ( ) ) )
144+ }
145+ }
146+
131147#[ pyclass(
132148 name = "_SimpleCData" ,
133149 base = "PyCData" ,
134- module = "_ctypes"
135- // TODO: metaclass
150+ module = "_ctypes" ,
151+ metaclass = "PySimpleMeta"
136152) ]
137153#[ derive( PyPayload ) ]
138154pub struct PyCSimple {
@@ -150,16 +166,44 @@ impl Debug for PyCSimple {
150166
151167#[ pyclass( flags( BASETYPE ) ) ]
152168impl PyCSimple {
169+ #[ pymethod( magic) ]
170+ pub fn __init__ ( & self , value : OptionalArg , vm : & VirtualMachine ) -> PyResult < ( ) > {
171+ if let Some ( ref v) = value. into_option ( ) {
172+ let content = set_primitive ( self . _type_ . as_str ( ) , v, vm) ?;
173+ self . value . store ( content) ;
174+ } else {
175+ self . value . store ( match self . _type_ . as_str ( ) {
176+ "c" | "u" => PyObjectRef :: from ( vm. ctx . new_bytes ( vec ! [ 0 ] ) ) ,
177+ "b" | "B" | "h" | "H" | "i" | "I" | "l" | "q" | "L" | "Q" => PyObjectRef :: from ( vm. ctx . new_int ( 0 ) ) ,
178+ "f" | "d" | "g" => PyObjectRef :: from ( vm. ctx . new_float ( 0.0 ) ) ,
179+ "?" => PyObjectRef :: from ( vm. ctx . new_bool ( false ) ) ,
180+ _ => vm. ctx . none ( ) , // "z" | "Z" | "P"
181+ } ) ;
182+ }
183+ Ok ( ( ) )
184+ }
153185
154186 #[ pygetset( name = "value" ) ]
155- pub fn value ( & self ) -> PyObjectRef {
156- unsafe { ( * self . value . as_ptr ( ) ) . clone ( ) }
187+ pub fn value ( instance : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
188+ let cls = instance. class ( ) ;
189+ let subcls_vec = cls. subclasses . read ( ) ;
190+ for subcls in subcls_vec. iter ( ) {
191+ println ! ( "subcls {}" , subcls) ;
192+ }
193+ println ! ( "value {}" , cls. name( ) . to_string( ) ) ;
194+ let zelf: & Py < Self > = instance. downcast_ref ( ) . ok_or_else ( || {
195+ vm. new_type_error ( "cannot get value of instance" . to_string ( ) )
196+ } ) ?;
197+ Ok ( unsafe { ( * zelf. value . as_ptr ( ) ) . clone ( ) } )
157198 }
158199
159200 #[ pygetset( name = "value" , setter) ]
160- fn set_value ( & self , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
161- let content = set_primitive ( self . _type_ . as_str ( ) , & value, vm) ?;
162- self . value . store ( content) ;
201+ fn set_value ( instance : PyObjectRef , value : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
202+ let zelf: PyRef < Self > = instance. downcast ( ) . map_err ( |_| {
203+ vm. new_type_error ( "cannot set value of instance" . to_string ( ) )
204+ } ) ?;
205+ let content = set_primitive ( zelf. _type_ . as_str ( ) , & value, vm) ?;
206+ zelf. value . store ( content) ;
163207 Ok ( ( ) )
164208 }
165209}
0 commit comments