pythonnet icon indicating copy to clipboard operation
pythonnet copied to clipboard

Resolution fails for an overloaded CLR method when providing mixed float & int arguments via Python

Open Dewb opened this issue 6 years ago • 3 comments

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

Dewb avatar Feb 05 '20 02:02 Dewb

Full repro case including project files: https://github.com/Dewb/PythonNetFloatTest

Dewb avatar Feb 05 '20 03:02 Dewb

@Dewb is this similar: https://github.com/pythonnet/pythonnet/issues/1099?

mjkkirschner avatar Apr 10 '20 19:04 mjkkirschner

@mjkkirschner As I explain here, this issue is not the same as #1099 .

tminka avatar Jan 03 '21 19:01 tminka