@@ -22,21 +22,98 @@ internal override bool CanSubclass()
22
22
23
23
public static IntPtr tp_new ( IntPtr tp , IntPtr args , IntPtr kw )
24
24
{
25
+ if ( kw != IntPtr . Zero )
26
+ {
27
+ return Exceptions . RaiseTypeError ( "array constructor takes no keyword arguments" ) ;
28
+ }
29
+
25
30
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 )
27
38
{
28
- return Exceptions . RaiseTypeError ( "array expects 1 argument" ) ;
39
+ return CreateMultidimensional ( self . type . GetElementType ( ) , dimensions , args , tp ) ;
29
40
}
41
+
30
42
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
+ }
31
57
object result ;
32
58
59
+ // this implements casting to Array[T]
33
60
if ( ! Converter . ToManaged ( op , self . type , out result , true ) )
34
61
{
35
62
return IntPtr . Zero ;
36
63
}
37
64
return CLRObject . GetInstHandle ( result , tp ) ;
38
65
}
39
66
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
+
40
117
41
118
/// <summary>
42
119
/// Implements __getitem__ for array types.