@@ -3,8 +3,9 @@ use crate::builtins::PyType;
33use crate :: builtins:: { PyBytes , PyFloat , PyInt , PyNone , PyStr , PyTypeRef } ;
44use crate :: convert:: ToPyObject ;
55use crate :: function:: { Either , OptionalArg } ;
6+ use crate :: protocol:: PyNumberMethods ;
67use crate :: stdlib:: ctypes:: _ctypes:: new_simple_type;
7- use crate :: types:: Constructor ;
8+ use crate :: types:: { AsNumber , Constructor } ;
89use crate :: { AsObject , Py , PyObjectRef , PyPayload , PyRef , PyResult , TryFromObject , VirtualMachine } ;
910use crossbeam_utils:: atomic:: AtomicCell ;
1011use num_traits:: ToPrimitive ;
@@ -158,9 +159,10 @@ pub struct PyCData {
158159impl PyCData { }
159160
160161#[ pyclass( module = "_ctypes" , name = "PyCSimpleType" , base = PyType ) ]
162+ #[ derive( Debug , PyPayload ) ]
161163pub struct PyCSimpleType { }
162164
163- #[ pyclass( flags( BASETYPE ) ) ]
165+ #[ pyclass( flags( BASETYPE ) , with ( AsNumber ) ) ]
164166impl PyCSimpleType {
165167 #[ allow( clippy:: new_ret_no_self) ]
166168 #[ pymethod]
@@ -186,6 +188,33 @@ impl PyCSimpleType {
186188
187189 PyCSimpleType :: from_param ( cls, as_parameter, vm)
188190 }
191+
192+ #[ pymethod]
193+ fn __mul__ ( cls : PyTypeRef , n : isize , vm : & VirtualMachine ) -> PyResult {
194+ PyCSimple :: repeat ( cls, n, vm)
195+ }
196+ }
197+
198+ impl AsNumber for PyCSimpleType {
199+ fn as_number ( ) -> & ' static PyNumberMethods {
200+ static AS_NUMBER : PyNumberMethods = PyNumberMethods {
201+ multiply : Some ( |a, b, vm| {
202+ // a is a PyCSimpleType instance (type object like c_char)
203+ // b is int (array size)
204+ let cls = a
205+ . downcast_ref :: < PyType > ( )
206+ . ok_or_else ( || vm. new_type_error ( "expected type" . to_owned ( ) ) ) ?;
207+ let n = b
208+ . try_index ( vm) ?
209+ . as_bigint ( )
210+ . to_isize ( )
211+ . ok_or_else ( || vm. new_overflow_error ( "array size too large" . to_owned ( ) ) ) ?;
212+ PyCSimple :: repeat ( cls. to_owned ( ) , n, vm)
213+ } ) ,
214+ ..PyNumberMethods :: NOT_IMPLEMENTED
215+ } ;
216+ & AS_NUMBER
217+ }
189218}
190219
191220#[ pyclass(
@@ -215,8 +244,18 @@ impl Constructor for PyCSimple {
215244 let attributes = cls. get_attributes ( ) ;
216245 let _type_ = attributes
217246 . iter ( )
218- . find ( |( k, _) | k. to_object ( ) . str ( vm) . unwrap ( ) . to_string ( ) == * "_type_" )
219- . unwrap ( )
247+ . find ( |( k, _) | {
248+ k. to_object ( )
249+ . str ( vm)
250+ . map ( |s| s. to_string ( ) == "_type_" )
251+ . unwrap_or ( false )
252+ } )
253+ . ok_or_else ( || {
254+ vm. new_type_error ( format ! (
255+ "cannot create '{}' instances: no _type_ attribute" ,
256+ cls. name( )
257+ ) )
258+ } ) ?
220259 . 1
221260 . str ( vm) ?
222261 . to_string ( ) ;
@@ -276,11 +315,6 @@ impl PyCSimple {
276315 }
277316 . to_pyobject ( vm) )
278317 }
279-
280- #[ pyclassmethod]
281- fn __mul__ ( cls : PyTypeRef , n : isize , vm : & VirtualMachine ) -> PyResult {
282- PyCSimple :: repeat ( cls, n, vm)
283- }
284318}
285319
286320impl PyCSimple {
0 commit comments