Skip to content

Commit 7cb1948

Browse files
committed
Implement System.Array constructor with base arg
1 parent 476ebae commit 7cb1948

File tree

2 files changed

+32
-10
lines changed

2 files changed

+32
-10
lines changed

Src/IronPython/Runtime/Operations/ArrayOps.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,23 @@ public static object __new__(CodeContext context, PythonType pythonType, ICollec
6767
}
6868

6969
[StaticExtensionMethod]
70-
public static object __new__(CodeContext context, PythonType pythonType, object items) {
70+
public static object __new__(CodeContext context, PythonType pythonType, object items)
71+
=> __new__(context, pythonType, items, @base: 0);
72+
73+
[StaticExtensionMethod]
74+
public static object __new__(CodeContext context, PythonType pythonType, object items, /*[KeywordOnly]*/ int @base) {
7175
Type type = pythonType.UnderlyingSystemType.GetElementType()!;
7276

73-
object? lenFunc;
74-
if (!PythonOps.TryGetBoundAttr(items, "__len__", out lenFunc))
77+
if (!PythonOps.TryGetBoundAttr(items, "__len__", out object? lenFunc))
7578
throw PythonOps.TypeErrorForBadInstance("expected object with __len__ function, got {0}", items);
7679

7780
int len = context.LanguageContext.ConvertToInt32(PythonOps.CallWithContext(context, lenFunc));
7881

79-
Array res = Array.CreateInstance(type, len);
82+
Array res = @base == 0 ?
83+
Array.CreateInstance(type, len) : Array.CreateInstance(type, [len], [@base]);
8084

8185
IEnumerator ie = PythonOps.GetEnumerator(items);
82-
int i = 0;
86+
int i = @base;
8387
while (ie.MoveNext()) {
8488
res.SetValue(Converter.Convert(ie.Current, type), i++);
8589
}
@@ -277,7 +281,7 @@ public static string __repr__(CodeContext/*!*/ context, [NotNone] Array/*!*/ sel
277281
}
278282
ret.Append(')');
279283
if (self.GetLowerBound(0) != 0) {
280-
ret.Append(", base: ");
284+
ret.Append(", base=");
281285
ret.Append(self.GetLowerBound(0));
282286
}
283287
ret.Append(')');

Tests/test_array.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,26 @@ def test_constructor(self):
198198
for y in range(array3.GetLength(1)):
199199
self.assertEqual(array3[x, y], 0)
200200

201+
def test_constructor_nonzero_lowerbound(self):
202+
# 1-based
203+
arr = System.Array[int]((1, 2), base=1)
204+
self.assertEqual(arr.Rank, 1)
205+
self.assertEqual(arr.Length, 2)
206+
self.assertEqual(arr.GetLowerBound(0), 1)
207+
self.assertEqual(arr.GetUpperBound(0), 2)
208+
self.assertEqual(arr[1], 1)
209+
self.assertEqual(arr[2], 2)
210+
for i in range(1, 3):
211+
self.assertEqual(arr[i], i)
212+
213+
def test_repr(self):
214+
from System import Array
215+
arr = Array[int]((5, 1), base=1)
216+
s = repr(arr)
217+
self.assertEqual(s, "Array[int]((5, 1), base=1)")
218+
array4eval = eval(s, globals(), locals())
219+
self.assertEqual(arr, array4eval)
220+
201221
def test_nonzero_lowerbound(self):
202222
a = System.Array.CreateInstance(int, (5,), (5,))
203223
for i in range(5, 5 + a.Length): a[i] = i
@@ -208,7 +228,7 @@ def test_nonzero_lowerbound(self):
208228
self.assertEqual(a[-1:-3:-1], System.Array[int]((9,8)))
209229
self.assertEqual(a[-1], 9)
210230

211-
self.assertEqual(repr(a), 'Array[int]((5, 6, 7, 8, 9), base: 5)')
231+
self.assertEqual(repr(a), 'Array[int]((5, 6, 7, 8, 9), base=5)')
212232

213233
a = System.Array.CreateInstance(int, (5,), (15,))
214234
b = System.Array.CreateInstance(int, (5,), (20,))
@@ -320,9 +340,7 @@ def test_base_negative(self):
320340

321341
# test slice indexing
322342
# 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
343+
arr1 = System.Array[int]((-1, 0, 1), base=-1)
326344
self.assertEqual(arr1[-1:1], System.Array[int]((-1, 0)))
327345
self.assertEqual(arr1[-2:1], System.Array[int]((-1, 0)))
328346
self.assertEqual(arr1[0:], System.Array[int]((0, 1)))

0 commit comments

Comments
 (0)