diff --git a/src/embed_tests/TestMethodBinder.cs b/src/embed_tests/TestMethodBinder.cs index 979592492..49b982d08 100644 --- a/src/embed_tests/TestMethodBinder.cs +++ b/src/embed_tests/TestMethodBinder.cs @@ -1402,6 +1402,35 @@ def call_method_with_enum(): Assert.AreEqual(DayOfWeek.Monday, CSharpModel.ProvidedArgument); } + [TestCase("call_non_generic_method", "GenericOverloadTestMethod")] + [TestCase("call_generic_method", "GenericOverloadTestMethod")] + [TestCase("call_generic_class_method", "GenericOverloadTestClass.GenericOverloadTestMethod")] + public void ResolvesToGenericOnlyWhenExplicitlyCalled(string pythonFuncToCall, string expectedMethodCalled) + { + using var _ = Py.GIL(); + + var module = PyModule.FromString($"ResolvesToGenericOnlyWhenExplicitlyCalled_{pythonFuncToCall}", @$" +from clr import AddReference +AddReference(""System"") +from Python.EmbeddingTest import * + +def call_non_generic_method(): + return TestMethodBinder.CSharpModel.GenericOverloadTestMethod(TestMethodBinder.CSharpModel(), 'Test') + +def call_generic_method(): + return TestMethodBinder.CSharpModel.GenericOverloadTestMethod[TestMethodBinder.CSharpModel](TestMethodBinder.CSharpModel(), 'Test') + +def call_generic_class_method(): + return GenericOverloadTestClass[TestMethodBinder.CSharpModel].GenericOverloadTestMethod(TestMethodBinder.CSharpModel(), 'Test') +"); + + Assert.DoesNotThrow(() => + { + using var result = module.GetAttr(pythonFuncToCall).Invoke(); + }); + Assert.AreEqual(expectedMethodCalled, CSharpModel.LastFuncCalled); + } + // Used to test that we match this function with Py DateTime & Date Objects public static int GetMonth(DateTime test) { @@ -1636,6 +1665,18 @@ public static void TestAction3(CSharpModel model1, CSharpModel model2) } LastFuncCalled = "TestAction3"; } + + public static string GenericOverloadTestMethod(CSharpModel testArg1, string testArg2, decimal testArgs3 = 0m) + { + LastFuncCalled = "GenericOverloadTestMethod"; + return string.Empty; + } + + public static T GenericOverloadTestMethod(CSharpModel testArg1, string testArg2, decimal testArgs3 = 0m) + { + LastFuncCalled = "GenericOverloadTestMethod"; + return default; + } } public class TestImplicitConversion @@ -1784,4 +1825,14 @@ public enum SomeEnu B = 2, } } + + public class GenericOverloadTestClass + { + public static T GenericOverloadTestMethod(T testArg1, string testArg2, decimal testArgs3 = 0m) + { + TestMethodBinder.CSharpModel.LastFuncCalled = "GenericOverloadTestClass.GenericOverloadTestMethod"; + return default; + + } + } } diff --git a/src/runtime/MethodBinder.cs b/src/runtime/MethodBinder.cs index 54fd33ff4..1f62f73d7 100644 --- a/src/runtime/MethodBinder.cs +++ b/src/runtime/MethodBinder.cs @@ -780,13 +780,11 @@ internal Binding Bind(BorrowedReference inst, BorrowedReference args, BorrowedRe else { bestMatch = matchesTouse - .GroupBy(x => x.KwargsMatched) - .OrderByDescending(x => x.Key) - .First() - .GroupBy(x => x.ImplicitOperations) - .OrderBy(x => x.Key) - .First() - .MinBy(x => GetMatchedArgumentsPrecedence(x.MethodInformation, pyArgCount, kwArgDict?.Keys)); + .OrderBy(x => x.Method.IsGenericMethod) + .ThenByDescending(x => x.KwargsMatched) + .ThenBy(x => x.ImplicitOperations) + .ThenBy(x => GetMatchedArgumentsPrecedence(x.MethodInformation, pyArgCount, kwArgDict?.Keys)) + .First(); } var margs = bestMatch.ManagedArgs; diff --git a/src/runtime/Properties/AssemblyInfo.cs b/src/runtime/Properties/AssemblyInfo.cs index 5e90074cf..b17e8cd57 100644 --- a/src/runtime/Properties/AssemblyInfo.cs +++ b/src/runtime/Properties/AssemblyInfo.cs @@ -4,5 +4,5 @@ [assembly: InternalsVisibleTo("Python.EmbeddingTest, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")] [assembly: InternalsVisibleTo("Python.Test, PublicKey=00240000048000009400000006020000002400005253413100040000110000005ffd8f49fb44ab0641b3fd8d55e749f716e6dd901032295db641eb98ee46063cbe0d4a1d121ef0bc2af95f8a7438d7a80a3531316e6b75c2dae92fb05a99f03bf7e0c03980e1c3cfb74ba690aca2f3339ef329313bcc5dccced125a4ffdc4531dcef914602cd5878dc5fbb4d4c73ddfbc133f840231343e013762884d6143189")] -[assembly: AssemblyVersion("2.0.52")] -[assembly: AssemblyFileVersion("2.0.52")] +[assembly: AssemblyVersion("2.0.53")] +[assembly: AssemblyFileVersion("2.0.53")] diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index 85aae5de1..981767b9e 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -5,7 +5,7 @@ Python.Runtime Python.Runtime QuantConnect.pythonnet - 2.0.52 + 2.0.53 false LICENSE https://github.com/pythonnet/pythonnet