diff --git a/Src/IronPython/Runtime/Operations/ArrayOps.cs b/Src/IronPython/Runtime/Operations/ArrayOps.cs index 87c4bcb62..fadaad2ba 100644 --- a/Src/IronPython/Runtime/Operations/ArrayOps.cs +++ b/Src/IronPython/Runtime/Operations/ArrayOps.cs @@ -67,19 +67,24 @@ public static object __new__(CodeContext context, PythonType pythonType, ICollec } [StaticExtensionMethod] - public static object __new__(CodeContext context, PythonType pythonType, object items) { + public static object __new__(CodeContext context, PythonType pythonType, object items) + => __new__(context, pythonType, items, @base: 0); + + [StaticExtensionMethod] + public static object __new__(CodeContext context, PythonType pythonType, object items, /*[KeywordOnly]*/ int @base) { Type type = pythonType.UnderlyingSystemType.GetElementType()!; - object? lenFunc; - if (!PythonOps.TryGetBoundAttr(items, "__len__", out lenFunc)) + if (!PythonOps.TryGetBoundAttr(items, "__len__", out object? lenFunc)) throw PythonOps.TypeErrorForBadInstance("expected object with __len__ function, got {0}", items); int len = context.LanguageContext.ConvertToInt32(PythonOps.CallWithContext(context, lenFunc)); - Array res = Array.CreateInstance(type, len); + + Array res = @base == 0 ? + Array.CreateInstance(type, len) : Array.CreateInstance(type, [len], [@base]); IEnumerator ie = PythonOps.GetEnumerator(items); - int i = 0; + int i = @base; while (ie.MoveNext()) { res.SetValue(Converter.Convert(ie.Current, type), i++); } @@ -274,7 +279,7 @@ public static string __repr__(CodeContext/*!*/ context, [NotNone] Array/*!*/ sel } ret.Append(')'); if (self.GetLowerBound(0) != 0) { - ret.Append(", base: "); + ret.Append(", base="); ret.Append(self.GetLowerBound(0)); } ret.Append(')'); diff --git a/Tests/test_array.py b/Tests/test_array.py index 6287ff46a..549958a3d 100644 --- a/Tests/test_array.py +++ b/Tests/test_array.py @@ -171,6 +171,26 @@ def test_constructor(self): for y in range(array3.GetLength(1)): self.assertEqual(array3[x, y], 0) + def test_constructor_nonzero_lowerbound(self): + # 1-based + arr = System.Array[int]((1, 2), base=1) + self.assertEqual(arr.Rank, 1) + self.assertEqual(arr.Length, 2) + self.assertEqual(arr.GetLowerBound(0), 1) + self.assertEqual(arr.GetUpperBound(0), 2) + self.assertEqual(arr[1], 1) + self.assertEqual(arr[2], 2) + for i in range(1, 3): + self.assertEqual(arr[i], i) + + def test_repr(self): + from System import Array + arr = Array[int]((5, 1), base=1) + s = repr(arr) + self.assertEqual(s, "Array[int]((5, 1), base=1)") + array4eval = eval(s, globals(), locals()) + self.assertEqual(arr, array4eval) + def test_nonzero_lowerbound(self): a = System.Array.CreateInstance(int, (5,), (5,)) for i in range(5): a[i] = i @@ -180,7 +200,7 @@ def test_nonzero_lowerbound(self): self.assertEqual(a[2:4], System.Array[int]((2,3))) self.assertEqual(a[-1], 4) - self.assertEqual(repr(a), 'Array[int]((0, 1, 2, 3, 4), base: 5)') + self.assertEqual(repr(a), 'Array[int]((0, 1, 2, 3, 4), base=5)') a = System.Array.CreateInstance(int, (5,), (15,)) b = System.Array.CreateInstance(int, (5,), (20,))