Skip to content

Commit 159e0dd

Browse files
committed
Allow implicit safe conversion to System.Double/Single in method calls
Checking the exact type beforehand is unnecessary and `AsDouble` will check whether `__float__` is available and call it. This is not yet supported for integer types, which would use `__int__` or `__index__` (for Python >=3.10), as the respective logic is for some reason only implemented for `AsLongLong` and `AsLong`, not for the unsigned counterparts and also not for the `AsSize_t` variants that we are using.
1 parent bd48dc1 commit 159e0dd

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/runtime/Converter.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -777,12 +777,8 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec
777777

778778
case TypeCode.Single:
779779
{
780-
if (!Runtime.PyFloat_Check(value) && !Runtime.PyInt_Check(value))
781-
{
782-
goto type_error;
783-
}
784780
double num = Runtime.PyFloat_AsDouble(value);
785-
if (num == -1.0 && Exceptions.ErrorOccurred())
781+
if (Exceptions.ErrorOccurred())
786782
{
787783
goto convert_error;
788784
}
@@ -799,12 +795,8 @@ internal static bool ToPrimitive(BorrowedReference value, Type obType, out objec
799795

800796
case TypeCode.Double:
801797
{
802-
if (!Runtime.PyFloat_Check(value) && !Runtime.PyInt_Check(value))
803-
{
804-
goto type_error;
805-
}
806798
double num = Runtime.PyFloat_AsDouble(value);
807-
if (num == -1.0 && Exceptions.ErrorOccurred())
799+
if (Exceptions.ErrorOccurred())
808800
{
809801
goto convert_error;
810802
}

tests/test_method.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,3 +1256,28 @@ 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 Answer:
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 FloatAnswer(Answer):
1272+
def __float__(self):
1273+
return 42.0
1274+
1275+
# TODO: This should also work for integer types but due to some complexities
1276+
# in the C-API functions (some call __int__/__index__, some don't), it's not
1277+
# supported, yet.
1278+
for v in [Answer(), FloatAnswer()]:
1279+
for t in [System.Double, System.Single]:
1280+
min_value = t(t.MinValue)
1281+
compare_to = min_value.CompareTo.__overloads__[t]
1282+
1283+
assert compare_to(v) == -1

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy