|
6 | 6 | ## Test array support by IronPython (System.Array) |
7 | 7 | ## |
8 | 8 |
|
| 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 | + |
9 | 29 | from iptest import IronPythonTestCase, is_cli, run_test, skipUnlessIronPython |
10 | 30 |
|
11 | 31 | if is_cli: |
@@ -146,6 +166,13 @@ def test_slice(self): |
146 | 166 | def f(): array1[::2] = [x * 2 for x in range(11)] |
147 | 167 | self.assertRaises(ValueError, f) |
148 | 168 |
|
| 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 | + |
149 | 176 | def test_creation(self): |
150 | 177 | t = System.Array |
151 | 178 | ti = type(System.Array.CreateInstance(int, 1)) |
@@ -239,6 +266,10 @@ def sliceArrayAssign(arr, index, val): |
239 | 266 | self.assertRaises(NotImplementedError, sliceArrayAssign, a, 1, 1) |
240 | 267 |
|
241 | 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 | + |
242 | 273 | # 1-based 2x2 matrix |
243 | 274 | arr = System.Array.CreateInstance(str, (2,2), (1,1)) |
244 | 275 |
|
@@ -267,6 +298,38 @@ def test_base1(self): |
267 | 298 | self.assertEqual(arr.GetValue(System.Array[System.Int32]((2,1))), "b_2,1") |
268 | 299 | self.assertEqual(arr.GetValue(System.Array[System.Int32]((2,2))), "b_2,2") |
269 | 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 | + |
270 | 333 | def test_array_type(self): |
271 | 334 |
|
272 | 335 | def type_helper(array_type, instance): |
|
0 commit comments