@@ -22,21 +22,98 @@ internal override bool CanSubclass()
2222
2323 public static IntPtr tp_new ( IntPtr tp , IntPtr args , IntPtr kw )
2424 {
25+ if ( kw != IntPtr . Zero )
26+ {
27+ return Exceptions . RaiseTypeError ( "array constructor takes no keyword arguments" ) ;
28+ }
29+
2530 var self = GetManagedObject ( tp ) as ArrayObject ;
26- if ( Runtime . PyTuple_Size ( args ) != 1 )
31+
32+ long [ ] dimensions = new long [ Runtime . PyTuple_Size ( args ) ] ;
33+ if ( dimensions . Length == 0 )
34+ {
35+ return Exceptions . RaiseTypeError ( "array constructor requires at least one integer argument or an object convertible to array" ) ;
36+ }
37+ if ( dimensions . Length != 1 )
2738 {
28- return Exceptions . RaiseTypeError ( "array expects 1 argument" ) ;
39+ return CreateMultidimensional ( self . type . GetElementType ( ) , dimensions , args , tp ) ;
2940 }
41+
3042 IntPtr op = Runtime . PyTuple_GetItem ( args , 0 ) ;
43+
44+ // create single dimensional array
45+ if ( Runtime . PyInt_Check ( op ) )
46+ {
47+ dimensions [ 0 ] = Runtime . PyLong_AsLongLong ( op ) ;
48+ if ( dimensions [ 0 ] == - 1 && Exceptions . ErrorOccurred ( ) )
49+ {
50+ Exceptions . Clear ( ) ;
51+ }
52+ else
53+ {
54+ return NewInstance ( self . type . GetElementType ( ) , tp , dimensions ) ;
55+ }
56+ }
3157 object result ;
3258
59+ // this implements casting to Array[T]
3360 if ( ! Converter . ToManaged ( op , self . type , out result , true ) )
3461 {
3562 return IntPtr . Zero ;
3663 }
3764 return CLRObject . GetInstHandle ( result , tp ) ;
3865 }
3966
67+ static IntPtr CreateMultidimensional ( Type elementType , long [ ] dimensions , IntPtr shapeTuple , IntPtr pyType )
68+ {
69+ for ( int dimIndex = 0 ; dimIndex < dimensions . Length ; dimIndex ++ )
70+ {
71+ IntPtr dimObj = Runtime . PyTuple_GetItem ( shapeTuple , dimIndex ) ;
72+ PythonException . ThrowIfIsNull ( dimObj ) ;
73+
74+ if ( ! Runtime . PyInt_Check ( dimObj ) )
75+ return Exceptions . RaiseTypeError ( "array constructor expects integer dimensions" ) ;
76+
77+ dimensions [ dimIndex ] = Runtime . PyLong_AsLongLong ( dimObj ) ;
78+ if ( dimensions [ dimIndex ] == - 1 && Exceptions . ErrorOccurred ( ) )
79+ {
80+ return Exceptions . RaiseTypeError ( "array constructor expects integer dimensions" ) ;
81+ }
82+ }
83+
84+ return NewInstance ( elementType , pyType , dimensions ) ;
85+ }
86+
87+ static IntPtr NewInstance ( Type elementType , IntPtr tp , long [ ] dimensions )
88+ {
89+ object result ;
90+ try
91+ {
92+ result = Array . CreateInstance ( elementType , dimensions ) ;
93+ }
94+ catch ( ArgumentException badArgument )
95+ {
96+ Exceptions . SetError ( Exceptions . ValueError , badArgument . Message ) ;
97+ return IntPtr . Zero ;
98+ }
99+ catch ( OverflowException overflow )
100+ {
101+ Exceptions . SetError ( overflow ) ;
102+ return IntPtr . Zero ;
103+ }
104+ catch ( NotSupportedException notSupported )
105+ {
106+ Exceptions . SetError ( notSupported ) ;
107+ return IntPtr . Zero ;
108+ }
109+ catch ( OutOfMemoryException oom )
110+ {
111+ Exceptions . SetError ( Exceptions . MemoryError , oom . Message ) ;
112+ return IntPtr . Zero ;
113+ }
114+ return CLRObject . GetInstHandle ( result , tp ) ;
115+ }
116+
40117
41118 /// <summary>
42119 /// Implements __getitem__ for array types.
0 commit comments