diff --git a/dev/MethodBinder.Tests/MethodBinderTests.cs b/dev/MethodBinder.Tests/MethodBinderTests.cs index 44b71b6be..381d17a27 100644 --- a/dev/MethodBinder.Tests/MethodBinderTests.cs +++ b/dev/MethodBinder.Tests/MethodBinderTests.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.InteropServices; using Python.Runtime; @@ -97,6 +96,16 @@ public void TestFooParam_2() t = I.Foo(IntPtr.Zero, 0); r = MethodInvoke.Invoke(I, M, args, NoKwargs); Assert.That(t, Is.EqualTo(r)); + + // Foo([Optional, DefaultParameterValue(12)] nint _1, uint _2) + args = new object[] { 0 }; + var kwargs = new KeywordArgs + { + ["_1"] = IntPtr.Zero, + }; + t = I.Foo(_1: IntPtr.Zero, 0); + r = MethodInvoke.Invoke(I, M, args, kwargs); + Assert.That(t, Is.EqualTo(r)); } } } diff --git a/src/runtime/MethodBinder.Invoke.cs b/src/runtime/MethodBinder.Invoke.cs index cb6bc23b1..6acdfe838 100644 --- a/src/runtime/MethodBinder.Invoke.cs +++ b/src/runtime/MethodBinder.Invoke.cs @@ -6,6 +6,7 @@ namespace Python.Runtime { using KeywordArgs = Dictionary; + using TypeDistMap = Dictionary; #if UNIT_TEST public static class MethodInvoke @@ -23,6 +24,8 @@ internal partial class MethodBinder static readonly Type UNINT = typeof(nuint); static readonly Type NINT = typeof(nint); + static readonly TypeDistMap s_distMap = new(); + private sealed class MatchArgSlot { readonly ParameterInfo _paramInfo; @@ -225,13 +228,17 @@ static uint GetDistance(Type from, Type to) { uint distance; + int key = from.GetHashCode() + to.GetHashCode(); + if (s_distMap.TryGetValue(key, out uint dist)) + { + return dist; + } + if (from == to) { distance = 0; } else if (from.IsAssignableFrom(to)) - //|| CanCast(from, to) - //|| CanCast(to, from)) { distance = 1; } @@ -244,6 +251,8 @@ static uint GetDistance(Type from, Type to) ); } + s_distMap[key] = distance; + return distance; }