diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs
index 420fc9435..dd8598e33 100644
--- a/src/runtime/converter.cs
+++ b/src/runtime/converter.cs
@@ -29,6 +29,8 @@ private Converter()
private static Type int64Type;
private static Type boolType;
private static Type typeType;
+ private static Type uint64Type;
+ private static Type uint32Type;
static Converter()
{
@@ -43,13 +45,15 @@ static Converter()
decimalType = typeof(Decimal);
boolType = typeof(Boolean);
typeType = typeof(Type);
+ uint64Type = typeof(UInt64);
+ uint32Type = typeof(UInt32);
}
///
/// Given a builtin Python type, return the corresponding CLR type.
///
- internal static Type GetTypeByAlias(IntPtr op)
+ internal static Type GetTypeByAlias(IntPtr op, Type preferred=null)
{
if (op == Runtime.PyStringType)
return stringType;
@@ -57,12 +61,18 @@ internal static Type GetTypeByAlias(IntPtr op)
if (op == Runtime.PyUnicodeType)
return stringType;
- if (op == Runtime.PyIntType)
+ if (op == Runtime.PyIntType && (preferred == null || preferred == int32Type))
return int32Type;
- if (op == Runtime.PyLongType)
+ if (op == Runtime.PyIntType && (preferred == null || preferred == uint32Type))
+ return uint32Type;
+
+ if (op == Runtime.PyLongType && (preferred == null || preferred == int64Type))
return int64Type;
+ if (op == Runtime.PyLongType && (preferred == null || preferred == uint64Type))
+ return uint64Type;
+
if (op == Runtime.PyFloatType)
return doubleType;
diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs
index 1b7cc4736..b72e3d963 100644
--- a/src/runtime/methodbinder.cs
+++ b/src/runtime/methodbinder.cs
@@ -330,6 +330,7 @@ public MatchedMethod(int kwargsMatched, int defaultsNeeded, object[] margs, int
ManagedArgs = margs;
Outs = outs;
Method = mb;
+ HasPyObjectParameter = mb.GetParameters().Any(x => x.ParameterType == typeof(PyObject));
}
public int KwargsMatched { get; }
@@ -337,6 +338,7 @@ public MatchedMethod(int kwargsMatched, int defaultsNeeded, object[] margs, int
public object[] ManagedArgs { get; }
public int Outs { get; }
public MethodBase Method { get; }
+ public bool HasPyObjectParameter { get; }
}
private readonly struct MismatchedMethod
@@ -470,8 +472,15 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, Meth
var matchedMethod = new MatchedMethod(kwargsMatched, defaultsNeeded, margs, outs, mi);
argMatchedMethods.Add(matchedMethod);
}
+
if (argMatchedMethods.Count > 0)
{
+ // order the matched methods such that PyObject overrides are last, we only care about
+ // this when there is more than one arg matched method
+ if (argMatchedMethods.Count > 1)
+ {
+ argMatchedMethods = argMatchedMethods.OrderBy(x => x.HasPyObjectParameter).ToList();
+ }
var bestKwargMatchCount = argMatchedMethods.Max(x => x.KwargsMatched);
var fewestDefaultsRequired = argMatchedMethods.Where(x => x.KwargsMatched == bestKwargMatchCount).Min(x => x.DefaultsNeeded);
@@ -725,7 +734,7 @@ static Type TryComputeClrArgumentType(Type parameterType, IntPtr argument, bool
pyoptype = Runtime.PyObject_Type(argument);
if (pyoptype != IntPtr.Zero)
{
- clrtype = Converter.GetTypeByAlias(pyoptype);
+ clrtype = Converter.GetTypeByAlias(pyoptype, parameterType);
}
Runtime.XDecref(pyoptype);
}
diff --git a/src/testing/conversiontest.cs b/src/testing/conversiontest.cs
index 1f9d64e1b..f67551bb7 100644
--- a/src/testing/conversiontest.cs
+++ b/src/testing/conversiontest.cs
@@ -42,7 +42,7 @@ public ConversionTest()
}
-
+
public interface ISpam
{
@@ -63,7 +63,7 @@ public string GetValue()
return value;
}
}
-
+
public class UnicodeString
{
public string value = "안녕";
@@ -78,4 +78,17 @@ public override string ToString()
return value;
}
}
+
+ public class MethodResolutionInt
+ {
+ public IEnumerable MethodA(ulong address, int size)
+ {
+ return new byte[10];
+ }
+
+ public int MethodA(string dummy, ulong address, int size)
+ {
+ return 0;
+ }
+ }
}
diff --git a/tests/test_conversion.py b/tests/test_conversion.py
index eec2bcde6..8fa972a3e 100644
--- a/tests/test_conversion.py
+++ b/tests/test_conversion.py
@@ -4,7 +4,7 @@
import pytest
import System
-from Python.Test import ConversionTest, UnicodeString
+from Python.Test import ConversionTest, UnicodeString, MethodResolutionInt
from Python.Runtime import PyObjectConversions
from Python.Runtime.Codecs import RawProxyEncoder
@@ -681,3 +681,15 @@ def CanEncode(self, clr_type):
l = ob.ListField
l.Add(42)
assert ob.ListField.Count == 1
+
+def test_int_param_resolution_required():
+ """Test resolution of `int` parameters when resolution is needed"""
+
+ mri = MethodResolutionInt()
+ data = list(mri.MethodA(0x1000, 10))
+ assert len(data) == 10
+ assert data[0] == 0
+
+ data = list(mri.MethodA(0x100000000, 10))
+ assert len(data) == 10
+ assert data[0] == 0