From 7cb19482b216012be1036d2da5b6c6cfdfc63691 Mon Sep 17 00:00:00 2001 From: Pavel Koneski Date: Fri, 29 Nov 2024 20:07:43 -0800 Subject: [PATCH] Implement System.Array constructor with base arg --- Src/IronPython/Runtime/Operations/ArrayOps.cs | 16 +++++++----- Tests/test_array.py | 26 ++++++++++++++++--- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Src/IronPython/Runtime/Operations/ArrayOps.cs b/Src/IronPython/Runtime/Operations/ArrayOps.cs index 60d2993b2..80b4ddc1d 100644 --- a/Src/IronPython/Runtime/Operations/ArrayOps.cs +++ b/Src/IronPython/Runtime/Operations/ArrayOps.cs @@ -67,19 +67,23 @@ 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++); } @@ -277,7 +281,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 97d0bc902..71dc5e6fe 100644 --- a/Tests/test_array.py +++ b/Tests/test_array.py @@ -198,6 +198,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, 5 + a.Length): a[i] = i @@ -208,7 +228,7 @@ def test_nonzero_lowerbound(self): self.assertEqual(a[-1:-3:-1], System.Array[int]((9,8))) self.assertEqual(a[-1], 9) - self.assertEqual(repr(a), 'Array[int]((5, 6, 7, 8, 9), base: 5)') + self.assertEqual(repr(a), 'Array[int]((5, 6, 7, 8, 9), base=5)') a = System.Array.CreateInstance(int, (5,), (15,)) b = System.Array.CreateInstance(int, (5,), (20,)) @@ -320,9 +340,7 @@ def test_base_negative(self): # test slice indexing # 1-dim array [-1, 0, 1] - arr1 = System.Array.CreateInstance(int, (3,), (-1,)) - for i in range(-1, 2): - arr1[i] = i + arr1 = System.Array[int]((-1, 0, 1), base=-1) self.assertEqual(arr1[-1:1], System.Array[int]((-1, 0))) self.assertEqual(arr1[-2:1], System.Array[int]((-1, 0))) self.assertEqual(arr1[0:], System.Array[int]((0, 1)))