66## Test array support by IronPython (System.Array)
77##
88
9+ """
10+ Indexing of CLI arrays in IronPython:
11+
12+
13+ | Base | Index >= 0 | Index < 0 |
14+ |------|--------------------------------------|-------------------|
15+ | > 0 | absolue | relative from end |
16+ | 0 | absolute == relative from beginning | relative from end |
17+ | < 0 | absolute | absolute |
18+
19+ Comparison to indexing in C# and CPython:
20+
21+ * Index >= 0, any base is C# compliant.
22+ * Base 0, any index is CPython compliant.
23+ * Base 0, index < 0 is not supported by C# but can be achieved by `System.Index` with 1-dim arrays only; then IronPython indexing is C# compliant.
24+ * Base > 0, index < 0 is not supported by C#; IronPython follows CPython convention as more practical.
25+ * Base < 0, index < 0 is C# compliant.
26+ * Base != 0 is not supported by CPython for any builtin structures.
27+ """
28+
929from iptest import IronPythonTestCase , is_cli , run_test , skipUnlessIronPython
1030
1131if is_cli :
@@ -146,6 +166,13 @@ def test_slice(self):
146166 def f (): array1 [::2 ] = [x * 2 for x in range (11 )]
147167 self .assertRaises (ValueError , f )
148168
169+ # slices on non-1-dim arrays are not supported
170+ array2 = System .Array .CreateInstance (int , 20 , 20 )
171+ self .assertRaises (NotImplementedError , lambda : array2 [:]) # TODO: TypeError?
172+ self .assertRaises (TypeError , lambda : array2 [:, :]) # TODO: NotImplementedError? This would work in Numpy and Sympy
173+ self .assertRaises (TypeError , lambda : array2 [:, :, :]) # OK
174+
175+
149176 def test_creation (self ):
150177 t = System .Array
151178 ti = type (System .Array .CreateInstance (int , 1 ))
@@ -173,35 +200,55 @@ def test_constructor(self):
173200
174201 def test_nonzero_lowerbound (self ):
175202 a = System .Array .CreateInstance (int , (5 ,), (5 ,))
176- for i in range (5 ): a [i ] = i
203+ for i in range (5 , 5 + a . Length ): a [i ] = i
177204
178- self .assertEqual (a [:2 ], System .Array [int ]((0 ,1 )))
179- self .assertEqual (a [2 :], System .Array [int ]((2 ,3 ,4 )))
180- self .assertEqual (a [2 :4 ], System .Array [int ]((2 ,3 )))
181- self .assertEqual (a [- 1 ], 4 )
205+ self .assertEqual (a [:7 ], System .Array [int ]((5 ,6 )))
206+ self .assertEqual (a [7 :], System .Array [int ]((7 ,8 ,9 )))
207+ self .assertEqual (a [7 :9 ], System .Array [int ]((7 ,8 )))
208+ self .assertEqual (a [- 1 :- 3 :- 1 ], System .Array [int ]((9 ,8 )))
209+ self .assertEqual (a [- 1 ], 9 )
182210
183- self .assertEqual (repr (a ), 'Array[int]((0, 1, 2, 3, 4 ), base: 5)' )
211+ self .assertEqual (repr (a ), 'Array[int]((5, 6, 7, 8, 9 ), base: 5)' )
184212
185213 a = System .Array .CreateInstance (int , (5 ,), (15 ,))
186214 b = System .Array .CreateInstance (int , (5 ,), (20 ,))
187215 self .assertEqual (a .Length , b .Length )
188216 for i in range (a .Length ):
189- self .assertEqual (a [i ], b [i ])
217+ self .assertEqual (a [i + 15 ], b [i + 20 ])
218+
219+ a0 = System .Array .CreateInstance (int , 5 ) # regular, 0-based
220+ for i in range (5 ): a0 [i ] = i
190221
191- ## 5-dimension
222+ a [17 :19 ] = a0 [2 :4 ]
223+ self .assertEqual (a [17 :19 ], System .Array [int ]((2 , 3 )))
224+
225+ self .assertEqual (a0 [3 :1 :- 1 ], System .Array [int ]((3 , 2 )))
226+ self .assertEqual (a [18 :16 :- 1 ], System .Array [int ]((3 , 2 )))
227+
228+ self .assertEqual (a0 [- 3 :- 1 ], System .Array [int ]((2 , 3 )))
229+ self .assertEqual (a [- 3 :- 1 ], System .Array [int ]((2 , 3 )))
230+
231+ a [18 :16 :- 1 ] = a0 [2 :4 ]
232+ self .assertEqual (a [17 :19 ], System .Array [int ]((3 , 2 )))
233+
234+ ## 5-dimension, 2-length/dim, progressive lowerbound
192235 a = System .Array .CreateInstance (int , (2 ,2 ,2 ,2 ,2 ), (1 ,2 ,3 ,4 ,5 ))
193- self .assertEqual (a [0 ,0 ,0 ,0 ,0 ], 0 )
236+ self .assertEqual (a [1 ,2 ,3 ,4 ,5 ], 0 )
237+
238+ ## 5-dimension, 2-length/dim, progressive lowerbound
239+ a = System .Array .CreateInstance (int , (2 ,2 ,2 ,2 ,2 ), (1 ,2 ,3 ,4 ,5 ))
240+ self .assertEqual (a [1 ,2 ,3 ,4 ,5 ], 0 )
194241
195242 for i in range (5 ):
196- index = [0 , 0 , 0 , 0 , 0 ]
197- index [i ] = 1
243+ index = [1 , 2 , 3 , 4 , 5 ]
244+ index [i ] + = 1
198245
199246 a [index [0 ], index [1 ], index [2 ], index [3 ], index [4 ]] = i
200247 self .assertEqual (a [index [0 ], index [1 ], index [2 ], index [3 ], index [4 ]], i )
201248
202249 for i in range (5 ):
203- index = [0 , 0 , 0 , 0 , 0 ]
204- index [i ] = 0
250+ index = [2 , 3 , 4 , 5 , 6 ]
251+ index [i ] -= 1
205252
206253 a [index [0 ], index [1 ], index [2 ], index [3 ], index [4 ]] = i
207254 self .assertEqual (a [index [0 ], index [1 ], index [2 ], index [3 ], index [4 ]], i )
@@ -218,6 +265,71 @@ def sliceArrayAssign(arr, index, val):
218265 self .assertRaises (NotImplementedError , sliceArrayAssign , a , - 200 , 1 )
219266 self .assertRaises (NotImplementedError , sliceArrayAssign , a , 1 , 1 )
220267
268+ def test_base1 (self ):
269+ # For positive base arrays, indices are indexing elements directly (in absolute terms)
270+ # rather than relative form the base.
271+ # Negative indices are indexing relative form the end.
272+
273+ # 1-based 2x2 matrix
274+ arr = System .Array .CreateInstance (str , (2 ,2 ), (1 ,1 ))
275+
276+ self .assertEqual (arr .GetLowerBound (0 ), 1 )
277+ self .assertEqual (arr .GetLowerBound (1 ), 1 )
278+ self .assertEqual (arr .GetUpperBound (0 ), 2 )
279+ self .assertEqual (arr .GetUpperBound (1 ), 2 )
280+
281+ arr .SetValue ("a_1,1" , System .Array [System .Int32 ]((1 ,1 )))
282+ arr .SetValue ("a_1,2" , System .Array [System .Int32 ]((1 ,2 )))
283+ arr .SetValue ("a_2,1" , System .Array [System .Int32 ]((2 ,1 )))
284+ arr .SetValue ("a_2,2" , System .Array [System .Int32 ]((2 ,2 )))
285+
286+ self .assertEqual (arr [1 , 1 ], "a_1,1" )
287+ self .assertEqual (arr [1 , 2 ], "a_1,2" )
288+ self .assertEqual (arr [2 , 1 ], "a_2,1" )
289+ self .assertEqual (arr [2 , 2 ], "a_2,2" )
290+
291+ arr [1 , 1 ] = "b_1,1"
292+ arr [1 , 2 ] = "b_1,2"
293+ arr [2 , 1 ] = "b_2,1"
294+ arr [2 , 2 ] = "b_2,2"
295+
296+ self .assertEqual (arr .GetValue (System .Array [System .Int32 ]((1 ,1 ))), "b_1,1" )
297+ self .assertEqual (arr .GetValue (System .Array [System .Int32 ]((1 ,2 ))), "b_1,2" )
298+ self .assertEqual (arr .GetValue (System .Array [System .Int32 ]((2 ,1 ))), "b_2,1" )
299+ self .assertEqual (arr .GetValue (System .Array [System .Int32 ]((2 ,2 ))), "b_2,2" )
300+
301+ def test_base_negative (self ):
302+ # For negative base arrays, negative indices are indexing elements directly (like non negative indices)
303+ # rather than indexing relative from the end.
304+
305+ # 2-dim array [-1, 0, 1] x [-1, 0, 1]
306+ arr = System .Array .CreateInstance (str , (3 ,3 ), (- 1 ,- 1 ))
307+ for i in range (- 1 , 2 ):
308+ for j in range (- 1 , 2 ):
309+ arr [i , j ] = "a_%d,%d" % (i , j )
310+
311+ for i in range (- 1 , 2 ):
312+ for j in range (- 1 , 2 ):
313+ self .assertEqual (arr [i , j ], "a_%d,%d" % (i , j ))
314+
315+ # test that VauleError is raised when the index is out of range
316+ self .assertRaises (IndexError , lambda : arr [- 2 , 0 ])
317+ self .assertRaises (IndexError , lambda : arr [2 , 0 ])
318+ self .assertRaises (IndexError , lambda : arr [0 , - 2 ])
319+ self .assertRaises (IndexError , lambda : arr [0 , 2 ])
320+
321+ # test slice indexing
322+ # 1-dim array [-1, 0, 1]
323+ arr1 = System .Array .CreateInstance (int , (3 ,), (- 1 ,))
324+ for i in range (- 1 , 2 ):
325+ arr1 [i ] = i
326+ self .assertEqual (arr1 [- 1 :1 ], System .Array [int ]((- 1 , 0 )))
327+ self .assertEqual (arr1 [- 2 :1 ], System .Array [int ]((- 1 , 0 )))
328+ self .assertEqual (arr1 [0 :], System .Array [int ]((0 , 1 )))
329+ self .assertEqual (arr1 [:1 ], System .Array [int ]((- 1 , 0 )))
330+ self .assertEqual (arr1 [:], System .Array [int ]((- 1 , 0 , 1 )))
331+ self .assertEqual (arr1 [:- 2 ], System .Array [int ](0 ))
332+
221333 def test_array_type (self ):
222334
223335 def type_helper (array_type , instance ):
0 commit comments