1+ use crossbeam_utils:: atomic:: AtomicCell ;
2+ use num_traits:: ToPrimitive ;
13use rustpython_common:: lock:: PyRwLock ;
24
3- use crate :: builtins:: PyType ;
5+ use crate :: builtins:: { PyType , PyTypeRef } ;
6+ use crate :: convert:: ToPyObject ;
7+ use crate :: protocol:: PyNumberMethods ;
48use crate :: stdlib:: ctypes:: PyCData ;
5- use crate :: { PyObjectRef , PyResult } ;
9+ use crate :: types:: AsNumber ;
10+ use crate :: { PyObjectRef , PyResult , VirtualMachine } ;
611
712#[ pyclass( name = "PyCPointerType" , base = PyType , module = "_ctypes" ) ]
813#[ derive( PyPayload , Debug ) ]
@@ -11,8 +16,44 @@ pub struct PyCPointerType {
1116 pub ( crate ) inner : PyCPointer ,
1217}
1318
14- #[ pyclass]
15- impl PyCPointerType { }
19+ #[ pyclass( flags( IMMUTABLETYPE ) , with( AsNumber ) ) ]
20+ impl PyCPointerType {
21+ #[ pymethod]
22+ fn __mul__ ( cls : PyTypeRef , n : isize , vm : & VirtualMachine ) -> PyResult {
23+ use super :: array:: { PyCArray , PyCArrayType } ;
24+ if n < 0 {
25+ return Err ( vm. new_value_error ( format ! ( "Array length must be >= 0, not {n}" ) ) ) ;
26+ }
27+ Ok ( PyCArrayType {
28+ inner : PyCArray {
29+ typ : PyRwLock :: new ( cls) ,
30+ length : AtomicCell :: new ( n as usize ) ,
31+ value : PyRwLock :: new ( vm. ctx . none ( ) ) ,
32+ } ,
33+ }
34+ . to_pyobject ( vm) )
35+ }
36+ }
37+
38+ impl AsNumber for PyCPointerType {
39+ fn as_number ( ) -> & ' static PyNumberMethods {
40+ static AS_NUMBER : PyNumberMethods = PyNumberMethods {
41+ multiply : Some ( |a, b, vm| {
42+ let cls = a
43+ . downcast_ref :: < PyType > ( )
44+ . ok_or_else ( || vm. new_type_error ( "expected type" . to_owned ( ) ) ) ?;
45+ let n = b
46+ . try_index ( vm) ?
47+ . as_bigint ( )
48+ . to_isize ( )
49+ . ok_or_else ( || vm. new_overflow_error ( "array size too large" . to_owned ( ) ) ) ?;
50+ PyCPointerType :: __mul__ ( cls. to_owned ( ) , n, vm)
51+ } ) ,
52+ ..PyNumberMethods :: NOT_IMPLEMENTED
53+ } ;
54+ & AS_NUMBER
55+ }
56+ }
1657
1758#[ pyclass(
1859 name = "_Pointer" ,
0 commit comments