@@ -20,21 +20,109 @@ internal override bool CanSubclass()
20
20
return false ;
21
21
}
22
22
23
- public static IntPtr tp_new ( IntPtr tp , IntPtr args , IntPtr kw )
23
+ public static IntPtr tp_new ( IntPtr tpRaw , IntPtr args , IntPtr kw )
24
24
{
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
+
25
32
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 )
27
36
{
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 " ) ;
29
38
}
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
+
30
47
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
+ }
31
63
object result ;
32
64
65
+ // this implements casting to Array[T]
33
66
if ( ! Converter . ToManaged ( op , self . type , out result , true ) )
34
67
{
35
68
return IntPtr . Zero ;
36
69
}
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
+ {
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
+ catch ( OutOfMemoryException oom )
121
+ {
122
+ Exceptions . SetError ( Exceptions . MemoryError , oom . Message ) ;
123
+ return default ;
124
+ }
125
+ return CLRObject . GetInstHandle ( result , arrayPyType ) ;
38
126
}
39
127
40
128
0 commit comments