Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Disambiguating an overloaded method with multiple parameters #1099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
integerfn opened this issue Apr 3, 2020 · 14 comments
Closed

Disambiguating an overloaded method with multiple parameters #1099

integerfn opened this issue Apr 3, 2020 · 14 comments

Comments

@integerfn
Copy link

integerfn commented Apr 3, 2020

Environment

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

Details

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)
@filmor
Copy link
Member

filmor commented Apr 3, 2020

Version 2.3.0 is outdated, can you reproduce the issue with 2.4 or the current master?

@integerfn
Copy link
Author

integerfn commented Apr 3, 2020

Version 2.3.0 is outdated, can you reproduce the issue with 2.4 or the current master?

Hi @filmor, thanks for the quick reply. I can confirm It does also happen in 2.4. I was unable to try with the current master because installation fails. I'm running python .\setup.py install and get the following error

Currently running NuGet.exe 5.4.0.
NuGet.exe is up to date.
Cannot find the specified version of msbuild: '14'
MSBuild auto-detection: using msbuild version '4.0' from 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319'.
All packages listed in packages.config are already installed.
error: [WinError 2] The system cannot find the file specified

If you feel it's important to try in the current master I can look into the error and keep trying.

I've updated the first post with a few more details.

@thegrima
Copy link

thegrima commented Jun 8, 2020

Hi,

I believe I've encountered the same problem (using pythonet 2.4.0 / python 2.7 / win10).

If it help, I was able to create a unit test using master branch to reproduce/demonstrate :
https://gist.github.com/thegrima/a62b32f0a3a982f4071e4fad5c57af2f

In short :

  • Two C# methods exists :
    public void Increment(double arg1)
    public void Increment(double arg1, int arg2)
    
  • Calling the 1 arg with int value from python fails :
    PythonEngine.Eval("lambda o: o.Increment(42)");
    

@chrislro2019
Copy link

Hi,

I can confirm the (mis)behavior as stated by @thegrima and I believe the issue still exists in pythonet 2.5.1 / python 2.7 / win10. I am not sure whether this is really solved by #1213 (for 2.5.2) as mentioned in #1211. NET function overloading should really work, this is a basic principle for OOP.

I already tried to give the signature when calling e.g., func[double, int](a,b) explicitly, but still python complains on calling it
TypeError: No match found for given type params
or (if not giving the signature)
TypeError: No method matches given arguments for func: (<type 'double'>, <type 'int'>)

Does anyone know a workaround?

@filmor
Copy link
Member

filmor commented Nov 11, 2020

If you are not sure whether this is fixed, please try it out.

.NET function overloading should really work, this is a basic principle for OOP.

This is a non-trivial problem and has nothing to do with basic principles. Python doesn't have a concept of overloading a function, not even with regard to the argument count, so all of this behaviour has to be manually implemented in this library.

Contributions of test-cases and possible fixes are always welcome.

@chrislro2019
Copy link

Sorry, I did not intended to complain in any way. You are right, my word were too harsh. I understand that this is non-trivial.

I checked with pip install --force-reinstall --pre git+https://github.com/pythonnet/pythonnet.git@1861beed8a34577a5a4c4bef753febd84fe1eecb#egg=pythonnet whether the commit fixed the problem for me, but it does not.

@thegrima
Copy link

Does anyone know a workaround?

Only way we found is to duplicate all C# methods to have all possible combination of arguments with double/int (our use case).
I've tried to take a look for a fix back then, but that's indeed very non-trivial.

@chrislro2019
Copy link

I played around the last couple of hours. When I call with explicit System based parameters from python to C# overload matching seems to work for 2.5.1 - a possible workaround (?):

import System
func(System.Double(a), System.Int32(b))

@tminka
Copy link
Contributor

tminka commented Jan 3, 2021

The code that opened this issue fails because MyEnum.Success is implicitly converted to a Python integer, and when MyDictionary.Add is called with that integer, Python.NET doesn't know how to convert it into a System.Enum. It has nothing to do with overloading. This problem can be avoided by changing MyDictionary to have type Dictionary<MyEnum, BlockingCollection<ISomeInterface>>, so that Python.NET knows how to convert the integer.

The issue described by thegrima is a different problem, related to #1040. thegrima's code does rely on overloading because if Increment is not overloaded, then it works.

@thegrima
Copy link

thegrima commented Jan 4, 2021

Thanks for your feedback.
Should I copy the message/code on #1040 ?

@tminka
Copy link
Contributor

tminka commented Jan 4, 2021

Only if you want to. By leaving a message there, you will be notified of new activity on that issue. But you could also just subscribe to the issue.

@lostmsu
Copy link
Member

lostmsu commented Jan 4, 2021

BTW, I think we should disable implicit .NET enum <-> Python int conversion in 3.0. Any enums, that want to be converted can do so through codecs. @filmor thoughts?

@filmor
Copy link
Member

filmor commented Jan 5, 2021

I agree by default with all automatic conversion removals apart from int, float, str, and bool. When doing so, we should probably collect sensible codecs in a ticket to include them as optional features (e.g. a backwards-compatible enum->int codec or a new one that maps System.Enum to Python enum classes).

@lostmsu
Copy link
Member

lostmsu commented Sep 23, 2021

This should now be fixed in 3.0

@lostmsu lostmsu closed this as completed Sep 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants