@@ -20,21 +20,109 @@ internal override bool CanSubclass()
2020 return false ;
2121 }
2222
23- public static IntPtr tp_new ( IntPtr tp , IntPtr args , IntPtr kw )
23+ public static IntPtr tp_new ( IntPtr tpRaw , IntPtr args , IntPtr kw )
2424 {
25+ if ( kw != IntPtr . Zero )
26+ {
27+ return Exceptions . RaiseTypeError ( "array constructor takes no keyword arguments" ) ;
28+ }
29+
30+ var tp = new BorrowedReference ( tpRaw ) ;
31+
2532 var self = GetManagedObject ( tp ) as ArrayObject ;
26- if ( Runtime . PyTuple_Size ( args ) != 1 )
33+
34+ long [ ] dimensions = new long [ Runtime . PyTuple_Size ( args ) ] ;
35+ if ( dimensions . Length == 0 )
2736 {
28- return Exceptions . RaiseTypeError ( "array expects 1 argument" ) ;
37+ return Exceptions . RaiseTypeError ( "array constructor requires at least one integer argument or an object convertible to array " ) ;
2938 }
39+ if ( dimensions . Length != 1 )
40+ {
41+ return CreateMultidimensional ( self . type . GetElementType ( ) , dimensions ,
42+ shapeTuple : new BorrowedReference ( args ) ,
43+ pyType : tp )
44+ . DangerousMoveToPointerOrNull ( ) ;
45+ }
46+
3047 IntPtr op = Runtime . PyTuple_GetItem ( args , 0 ) ;
48+
49+ // create single dimensional array
50+ if ( Runtime . PyInt_Check ( op ) )
51+ {
52+ dimensions [ 0 ] = Runtime . PyLong_AsLongLong ( op ) ;
53+ if ( dimensions [ 0 ] == - 1 && Exceptions . ErrorOccurred ( ) )
54+ {
55+ Exceptions . Clear ( ) ;
56+ }
57+ else
58+ {
59+ return NewInstance ( self . type . GetElementType ( ) , tp , dimensions )
60+ . DangerousMoveToPointerOrNull ( ) ;
61+ }
62+ }
3163 object result ;
3264
65+ // this implements casting to Array[T]
3366 if ( ! Converter . ToManaged ( op , self . type , out result , true ) )
3467 {
3568 return IntPtr . Zero ;
3669 }
37- return CLRObject . GetInstHandle ( result , tp ) ;
70+ return CLRObject . GetInstHandle ( result , tp )
71+ . DangerousGetAddress ( ) ;
72+ }
73+
74+ static NewReference CreateMultidimensional ( Type elementType , long [ ] dimensions , BorrowedReference shapeTuple , BorrowedReference pyType )
75+ {
<
C0A6
/code>76+ for ( int dimIndex = 0 ; dimIndex < dimensions . Length ; dimIndex ++ )
77+ {
78+ BorrowedReference dimObj = Runtime . PyTuple_GetItem ( shapeTuple , dimIndex ) ;
79+ PythonException . ThrowIfIsNull ( dimObj ) ;
80+
81+ if ( ! Runtime . PyInt_Check ( dimObj ) )
82+ {
83+ Exceptions . RaiseTypeError ( "array constructor expects integer dimensions" ) ;
84+ return default ;
85+ }
86+
87+ dimensions [ dimIndex ] = Runtime . PyLong_AsLongLong ( dimObj ) ;
88+ if ( dimensions [ dimIndex ] == - 1 && Exceptions . ErrorOccurred ( ) )
89+ {
90+ Exceptions . RaiseTypeError ( "array constructor expects integer dimensions" ) ;
91+ return default ;
92+ }
93+ }
94+
95+ return NewInstance ( elementType , pyType , dimensions ) ;
96+ }
97+
98+ static NewReference NewInstance ( Type elementType , BorrowedReference arrayPyType , long [ ] dimensions )
99+ {
100+ object result ;
101+ try
102+ {
103+ result = Array . CreateInstance ( elementType , dimensions ) ;
104+ }
105+ catch ( ArgumentException badArgument )
106+ {
107+ Exceptions . SetError ( Exceptions . ValueError , badArgument . Message ) ;
108+ return default ;
109+ }
110+ catch ( OverflowException overflow )
111+ {
112+ Exceptions . SetError ( overflow ) ;
113+ return default ;
114+ }
115+ catch ( NotSupportedException notSupported )
116+ {
117+ Exceptions . SetError ( notSupported ) ;
118+ return default ;
119+ }
120+
8090
catch ( OutOfMemoryException oom )
121+ {
122+ Exceptions . SetError ( Exceptions . MemoryError , oom . Message ) ;
123+ return default ;
124+ }
125+ return CLRObject . GetInstHandle ( result , arrayPyType ) ;
38126 }
39127
40128
0 commit comments