Skip to content

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

@Dewb

Description

@Dewb

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions