Skip to content

Commit 32fdc9c

Browse files
authored
Disable implicit conversion from PyFloat to array index (#1363)
1 parent 7e7cbca commit 32fdc9c

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

src/runtime/arrayobject.cs

+23
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,10 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
159159

160160
if (rank == 1)
161161
{
162+
if (!Runtime.PyInt_Check(idx))
163+
{
164+
return RaiseIndexMustBeIntegerError(idx);
165+
}
162166
index = Runtime.PyInt_AsLong(idx);
163167

164168
if (Exceptions.ErrorOccurred())
@@ -199,6 +203,10 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
199203
for (var i = 0; i < count; i++)
200204
{
201205
IntPtr op = Runtime.PyTuple_GetItem(idx, i);
206+
if (!Runtime.PyInt_Check(op))
207+
{
208+
return RaiseIndexMustBeIntegerError(op);
209+
}
202210
index = Runtime.PyInt_AsLong(op);
203211

204212
if (Exceptions.ErrorOccurred())
@@ -253,6 +261,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
253261

254262
if (rank == 1)
255263
{
264+
if (!Runtime.PyInt_Check(idx))
265+
{
266+
RaiseIndexMustBeIntegerError(idx);
267+
return -1;
268+
}
256269
index = Runtime.PyInt_AsLong(idx);
257270

258271
if (Exceptions.ErrorOccurred())
@@ -291,6 +304,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
291304
for (var i = 0; i < count; i++)
292305
{
293306
IntPtr op = Runtime.PyTuple_GetItem(idx, i);
307+
if (!Runtime.PyInt_Check(op))
308+
{
309+
RaiseIndexMustBeIntegerError(op);
310+
return -1;
311+
}
294312
index = Runtime.PyInt_AsLong(op);
295313

296314
if (Exceptions.ErrorOccurred())
@@ -320,6 +338,11 @@ static NewReference NewInstance(Type elementType, BorrowedReference arrayPyType,
320338
return 0;
321339
}
322340

341+
private static IntPtr RaiseIndexMustBeIntegerError(IntPtr idx)
342+
{
343+
string tpName = Runtime.PyObject_GetTypeName(idx);
344+
return Exceptions.RaiseTypeError($"array index has type {tpName}, expected an integer");
345+
}
323346

324347
/// <summary>
325348
/// Implements __contains__ for array types.

src/tests/test_array.py

+33-2
Original file line numberDiff line numberDiff line change
@@ -836,8 +836,15 @@ def test_typed_array():
836836

837837
with pytest.raises(TypeError):
838838
ob = Test.TypedArrayTest()
839-
ob.items["wrong"] = "wrong"
839+
ob.items["wrong"] = Spam("0")
840+
841+
with pytest.raises(TypeError):
842+
ob = Test.TypedArrayTest()
843+
_ = ob.items[0.5]
840844

845+
with pytest.raises(TypeError):
846+
ob = Test.TypedArrayTest()
847+
ob.items[0.5] = Spam("0")
841848

842849
def test_multi_dimensional_array():
843850
"""Test multi-dimensional arrays."""
@@ -901,8 +908,23 @@ def test_multi_dimensional_array():
901908

902909
with pytest.raises(TypeError):
903910
ob = Test.MultiDimensionalArrayTest()
904-
ob[0, 0] = "wrong"
911+
ob.items[0, 0] = "wrong"
905912

913+
with pytest.raises(TypeError):
914+
ob = Test.MultiDimensionalArrayTest()
915+
ob["0", 0] = 0
916+
917+
with pytest.raises(TypeError):
918+
ob = Test.MultiDimensionalArrayTest()
919+
ob.items["0", 0] = 0
920+
921+
with pytest.raises(TypeError):
922+
ob = Test.MultiDimensionalArrayTest()
923+
_ = ob.items[0.5, 0]
924+
925+
with pytest.raises(TypeError):
926+
ob = Test.MultiDimensionalArrayTest()
927+
ob.items[0.5, 0] = 0
906928

907929
def test_array_iteration():
908930
"""Test array iteration."""
@@ -1189,6 +1211,15 @@ def test_create_array_from_shape():
11891211
with pytest.raises(ValueError):
11901212
Array[int](-1)
11911213

1214+
with pytest.raises(TypeError):
1215+
Array[int]('1')
1216+
1217+
with pytest.raises(ValueError):
1218+
Array[int](-1, -1)
1219+
1220+
with pytest.raises(TypeError):
1221+
Array[int]('1', '1')
1222+
11921223
def test_special_array_creation():
11931224
"""Test using the Array[<type>] syntax for creating arrays."""
11941225
from Python.Test import ISayHello1, InterfaceTest, ShortEnum

0 commit comments

Comments
 (0)