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 } ;
3
3
use crossbeam_utils:: atomic:: AtomicCell ;
4
4
use num_traits:: ToPrimitive ;
5
5
use rustpython_common:: lock:: PyRwLock ;
6
6
use std:: fmt:: Debug ;
7
+ use crate :: function:: { Either , OptionalArg } ;
8
+ use crate :: stdlib:: ctypes:: _ctypes:: new_simple_type;
9
+ use crate :: builtins:: PyType ;
7
10
8
11
#[ allow( dead_code) ]
9
12
fn set_primitive ( _type_ : & str , value : & PyObjectRef , vm : & VirtualMachine ) -> PyResult {
@@ -128,11 +131,24 @@ pub struct PyCData {
128
131
#[ pyclass]
129
132
impl PyCData { }
130
133
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
+
131
147
#[ pyclass(
132
148
name = "_SimpleCData" ,
133
149
base = "PyCData" ,
134
- module = "_ctypes"
135
- // TODO: metaclass
150
+ module = "_ctypes" ,
151
+ metaclass = "PySimpleMeta"
136
152
) ]
137
153
#[ derive( PyPayload ) ]
138
154
pub struct PyCSimple {
@@ -150,16 +166,44 @@ impl Debug for PyCSimple {
150
166
151
167
#[ pyclass( flags( BASETYPE ) ) ]
152
168
impl 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
+ }
153
185
154
186
#[ 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 ( ) } )
157
198
}
158
199
159
200
#[ 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) ;
163
207
Ok ( ( ) )
164
208
}
165
209
}
0 commit comments