diff --git a/src/runtime/Converter.cs b/src/runtime/Converter.cs index 2e0edc3b5..3c46e9034 100644 --- a/src/runtime/Converter.cs +++ b/src/runtime/Converter.cs @@ -710,7 +710,7 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec { if (Runtime.Is32Bit) { - if (!Runtime.PyLong_Check(value)) + if (!Runtime.PyInt_Check(value)) { goto type_error; } diff --git a/src/runtime/Runtime.cs b/src/runtime/Runtime.cs index 4dc904f43..6238119ff 100644 --- a/src/runtime/Runtime.cs +++ b/src/runtime/Runtime.cs @@ -1101,11 +1101,6 @@ internal static bool PyBool_Check(BorrowedReference ob) internal static NewReference PyInt_FromInt64(long value) => PyLong_FromLongLong(value); - internal static bool PyLong_Check(BorrowedReference ob) - { - return PyObject_TYPE(ob) == PyLongType; - } - internal static NewReference PyLong_FromLongLong(long value) => Delegates.PyLong_FromLongLong(value); @@ -1145,9 +1140,7 @@ internal static NewReference PyLong_FromString(string value, int radix) } internal static bool PyFloat_Check(BorrowedReference ob) - { - return PyObject_TYPE(ob) == PyFloatType; - } + => PyObject_TypeCheck(ob, PyFloatType); /// /// Return value: New reference. diff --git a/tests/test_method.py b/tests/test_method.py index b24b525aa..b86bbd6b4 100644 --- a/tests/test_method.py +++ b/tests/test_method.py @@ -1256,3 +1256,41 @@ def test_method_encoding(): def test_method_with_pointer_array_argument(): with pytest.raises(TypeError): MethodTest.PointerArray([0]) + +def test_method_call_implicit_conversion(): + + class IntAnswerMixin: + # For Python >= 3.8 + def __index__(self): + return 42 + + # For Python < 3.10 + def __int__(self): + return 42 + + class Answer(int, IntAnswerMixin): + pass + + class FloatAnswer(float, IntAnswerMixin): + def __float__(self): + return 42.0 + + # TODO: This should also work for integer types but due to some complexities + # in the C-API functions (some call __int__/__index__, some don't), it's not + # supported, yet. + for v in [Answer(), FloatAnswer()]: + for t in [System.Double, System.Single]: + min_value = t(t.MinValue) + compare_to = min_value.CompareTo.__overloads__[t] + + assert compare_to(v) == -1 + + class SomeNonFloat: + def __float__(self): + return 42.0 + + for t in [System.Double, System.Single]: + with pytest.raises(TypeError): + min_value = t(t.MinValue) + compare_to = min_value.CompareTo.__overloads__[t] + assert compare_to(SomeNonFloat()) == -1