Skip to content

Commit 9a09f11

Browse files
committed
Fix implicit float conversion for classes that derive from float
1 parent f1ef11d commit 9a09f11

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

src/runtime/Converter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec
782782
goto type_error;
783783
}
784784
double num = Runtime.PyFloat_AsDouble(value);
785-
if (num == -1.0 && Exceptions.ErrorOccurred())
785+
if (Exceptions.ErrorOccurred())
786786
{
787787
goto convert_error;
788788
}
@@ -804,7 +804,7 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec
804804
goto type_error;
805805
}
806806
double num = Runtime.PyFloat_AsDouble(value);
807-
if (num == -1.0 && Exceptions.ErrorOccurred())
807+
if (Exceptions.ErrorOccurred())
808808
{
809809
goto convert_error;
810810
}

src/runtime/Runtime.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,9 +1145,7 @@ internal static NewReference PyLong_FromString(string value, int radix)
11451145
}
11461146

11471147
internal static bool PyFloat_Check(BorrowedReference ob)
1148-
{
1149-
return PyObject_TYPE(ob) == PyFloatType;
1150-
}
1148+
=> PyObject_TypeCheck(ob, PyFloatType);
11511149

11521150
/// <summary>
11531151
/// Return value: New reference.

tests/test_method.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,3 +1256,41 @@ def test_method_encoding():
12561256
def test_method_with_pointer_array_argument():
12571257
with pytest.raises(TypeError):
12581258
MethodTest.PointerArray([0])
1259+
1260+
def test_method_call_implicit_conversion():
1261+
1262+
class IntAnswerMixin:
1263+
# For Python >= 3.8
1264+
def __index__(self):
1265+
return 42
1266+
1267+
# For Python < 3.10
1268+
def __int__(self):
1269+
return 42
1270+
1271+
class Answer(int, IntAnswerMixin):
1272+
pass
1273+
1274+
class FloatAnswer(float, IntAnswerMixin):
1275+
def __float__(self):
1276+
return 42.0
1277+
1278+
# TODO: This should also work for integer types but due to some complexities
1279+
# in the C-API functions (some call __int__/__index__, some don't), it's not
1280+
# supported, yet.
1281+
for v in [Answer(), FloatAnswer()]:
1282+
for t in [System.Double, System.Single]:
1283+
min_value = t(t.MinValue)
1284+
compare_to = min_value.CompareTo.__overloads__[t]
1285+
1286+
assert compare_to(v) == -1
1287+
1288+
class SomeNonFloat:
1289+
def __float__(self):
1290+
return 42.0
1291+
1292+
for t in [System.Double, System.Single]:
1293+
with pytest.raises(TypeError):
1294+
min_value = t(t.MinValue)
1295+
compare_to = min_value.CompareTo.__overloads__[t]
1296+
assert compare_to(SomeNonFloat()) == -1

0 commit comments

Comments
 (0)