Repository: pythonnet/pythonnet

Issue #1099: Disambiguating an overloaded method with multiple parameters
Created: 2020-04-03T13:31:25Z
Environment

Pythonnet version: 2.3.0 and 2.4.0
Python version: 3.6.5
Operating System: W10

Details

I'm having issues disambiguating an overloaded C# method that has multiple parameters. I've found #935 which is a very similar issue but can't get it to work. I'm following the same steps but I still get the same error.

The C# side
    public enum MyEnum: byte
    {
        Success= (byte)'S',
        Error = (byte)'E'
    }

    public class MyClass
    {
        public Dictionary<Enum, BlockingCollection<ISomeInterface>> MyDictionary { get; }

        public MyClass()
        {
            MyDictionary = new Dictionary<Enum, BlockingCollection<ISomeInterface>>(); 
        }
    }
On the python side, I began with this code
    from System.Collections.Concurrent import BlockingCollection
    from MyModule import MyClass, ISomeInterface, MyEnum

    obj = MyClass()
    collection = BlockingCollection[ISomeInterface]()
    obj.MyDictionary.Add(MyEnum.Success, collection)
This fails with TypeError: No method matches given arguments for Add. I've tried what seemed to solve it for #935 but get the same results
    from System.Collections.Concurrent import BlockingCollection
    from System import Enum
    from MyModule import MyClass, ISomeInterface, MyEnum

    obj = MyClass()
    collection = BlockingCollection[ISomeInterface]()
    obj.MyDictionary.Add[Enum, BlockingCollection[ISomeInterface]](MyEnum.Success, collection)
This fails with TypeError: No match found for given type params

The output of print(obj.MyDictionary.Add.__overloads__) is

    Void Add(System.Enum, System.Collections.Concurrent.BlockingCollection`1[MyModule.ISomeInterface])
UPDATE
Running this code alone actually works, add shows as a bound method in the debugger:
add = obj.MyDictionary.Add.Overloads[Enum, BlockingCollection[ISomeInterface]]
However, attempting to call the function always fails. I've attempted passing System.byte and 0, instead of the enum, but none of them work.
add(MyEnum.Success, collection)
obj.MyDictionary.Add[Enum, BlockingCollection[ISomeInterface]](MyEnum.Success, collection)
obj.MyDictionary.Add.Overloads[Enum, BlockingCollection[ISomeInterface]](MyEnum.Success, collection)

Duplicate issue #1040: Resolution fails for an overloaded CLR method when providing mixed float & int arguments via Python
Created: 2020-02-05T02:51:09Z
Environment

Pythonnet version: 2.4.0
Python version: 3.7.6
Operating System: Windows 10

Details
Given a CLR method Foo with overloads Foo(int a, int b) and Foo(float a, float b), calling Foo from Python with one int and one float argument results in a TypeError: no method matches given arguments for Foo.
If the method is not overloaded and only exists in the Foo(float a, float b) form, then calling from Python with one int and one float works fine, as does two ints, since the int arguments can be freely converted to float. The existence of the overload prevents this somehow.
I looked through the existing method resolution issues and didn't see this case.
Full example
MyModule\MyClass.cs
using System;

namespace MyModule
{
    public class MyClass
    {
        public static float Add(float a, float b)
        {
            return a + b;
        }
        
        public static int Add(int a, int b)
        {
            return a + b;
        }
    }
}
PythonNetFloatTest\Program.cs
using Python.Runtime;

namespace PythonNetFloatTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string preamble =
                "import clr\n" +
                "clr.AddReference('MyModule')\n" +
                "from MyModule import MyClass\n" +
                "import sys\n" +
                "print(sys.version)";

            string callWithFloatArgs = "result = MyClass.Add(1.0, 2.0)";
            string callWithIntArgs   = "result = MyClass.Add(1, 2)";
            string callWithMixedArgs = "result = MyClass.Add(1.0, 2)";

            PythonEngine.Initialize();
            using (Py.GIL())
            {
                using (PyScope scope = Py.CreateScope())
                {
                    scope.Exec(preamble);
                    
                    scope.Exec(callWithFloatArgs);
                    System.Console.WriteLine(scope.Get("result")); // prints "3.0"

                    scope.Exec(callWithIntArgs);
                    System.Console.WriteLine(scope.Get("result")); // prints "3"

                    scope.Exec(callWithMixedArgs); // throws Python.Runtime.PythonException: 
                                                   // 'TypeError : No method matches given arguments for Add'
                    System.Console.WriteLine(scope.Get("result"));
                }
            }
        }
    }
}
Output:
3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]
3.0
3

Unhandled Exception: Python.Runtime.PythonException: TypeError : No method matches given arguments for Add
   at Python.Runtime.Runtime.CheckExceptionOccurred()
   at Python.Runtime.PyScope.Exec(String code, IntPtr _globals, IntPtr _locals)
   at PythonNetFloatTest.Program.Main(String[] args) in .\PythonNetFloatTest\PythonNetFloatTest\Program.cs:line 33

If you remove the public static int Add(int a, int b) overload from MyModule, the output is instead:
3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]
3.0
3.0
3.0

Closing comment (2021-01-03T19:47:09Z): @mjkkirschner As I explain here, this issue is not the same as #1099 .