diff --git a/src/runtime/arrayobject.cs b/src/runtime/arrayobject.cs index 282383f86..5c97c6dbf 100644 --- a/src/runtime/arrayobject.cs +++ b/src/runtime/arrayobject.cs @@ -159,6 +159,10 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType, if (rank == 1) { + if (!Runtime.PyInt_Check(idx)) + { + return RaiseIndexMustBeIntegerError(idx); + } index = Runtime.PyInt_AsLong(idx); if (Exceptions.ErrorOccurred()) @@ -199,6 +203,10 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType, for (var i = 0; i < count; i++) { IntPtr op = Runtime.PyTuple_GetItem(idx, i); + if (!Runtime.PyInt_Check(op)) + { + return RaiseIndexMustBeIntegerError(op); + } index = Runtime.PyInt_AsLong(op); if (Exceptions.ErrorOccurred()) @@ -253,6 +261,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType, if (rank == 1) { + if (!Runtime.PyInt_Check(idx)) + { + RaiseIndexMustBeIntegerError(idx); + return -1; + } index = Runtime.PyInt_AsLong(idx); if (Exceptions.ErrorOccurred()) @@ -291,6 +304,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType, for (var i = 0; i < count; i++) { IntPtr op = Runtime.PyTuple_GetItem(idx, i); + if (!Runtime.PyInt_Check(op)) + { + RaiseIndexMustBeIntegerError(op); + return -1; + } index = Runtime.PyInt_AsLong(op); if (Exceptions.ErrorOccurred()) @@ -320,6 +338,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType, return 0; } + private static IntPtr RaiseIndexMustBeIntegerError(IntPtr idx) + { + string tpName = Runtime.PyObject_GetTypeName(idx); + return Exceptions.RaiseTypeError($"array index has type {tpName}, expected an integer"); + } /// /// Implements __contains__ for array types. diff --git a/src/tests/test_array.py b/src/tests/test_array.py index 9ab044b29..232c89ac7 100644 --- a/src/tests/test_array.py +++ b/src/tests/test_array.py @@ -836,8 +836,15 @@ def test_typed_array(): with pytest.raises(TypeError): ob = Test.TypedArrayTest() - ob.items["wrong"] = "wrong" + ob.items["wrong"] = Spam("0") + + with pytest.raises(TypeError): + ob = Test.TypedArrayTest() + _ = ob.items[0.5] + with pytest.raises(TypeError): + ob = Test.TypedArrayTest() + ob.items[0.5] = Spam("0") def test_multi_dimensional_array(): """Test multi-dimensional arrays.""" @@ -901,8 +908,23 @@ def test_multi_dimensional_array(): with pytest.raises(TypeError): ob = Test.MultiDimensionalArrayTest() - ob[0, 0] = "wrong" + ob.items[0, 0] = "wrong" + with pytest.raises(TypeError): + ob = Test.MultiDimensionalArrayTest() + ob["0", 0] = 0 + + with pytest.raises(TypeError): + ob = Test.MultiDimensionalArrayTest() + ob.items["0", 0] = 0 + + with pytest.raises(TypeError): + ob = Test.MultiDimensionalArrayTest() + _ = ob.items[0.5, 0] + + with pytest.raises(TypeError): + ob = Test.MultiDimensionalArrayTest() + ob.items[0.5, 0] = 0 def test_array_iteration(): """Test array iteration.""" @@ -1189,6 +1211,15 @@ def test_create_array_from_shape(): with pytest.raises(ValueError): Array[int](-1) + with pytest.raises(TypeError): + Array[int]('1') + + with pytest.raises(ValueError): + Array[int](-1, -1) + + with pytest.raises(TypeError): + Array[int]('1', '1') + def test_special_array_creation(): """Test using the Array[] syntax for creating arrays.""" from Python.Test import ISayHello1, InterfaceTest, ShortEnum