pythonnet icon indicating copy to clipboard operation
pythonnet copied to clipboard

Cannot get correct overload of generic method

Open Tobimaru opened this issue 7 years ago • 7 comments

Environment

  • Pythonnet version: zip archive of master branch
  • Python version: 3.6
  • Operating System: Ubuntu 18.04

Details

  • Describe what you were trying to get done.

Invoke a generic method with multiple overloads.

  • What commands did you run to trigger this issue?

On the C# side I have the following generic method with overloads:

Variable<T> Variable.Constant<T>(T)
VariableArray<T> Variable.Constant<T>(T[])    

On the python side, I'm trying to invoke the second overload by doing:

a = Variable.Constant(System.Array[System.Double]([1.0, 2.0, 3.0]))

But when I check the type of a, it gives Variable[System.Double[]] and not VariableArray[System.Double]. This makes sense since it's ambiguous without specifying the type of the output variable or specifying the type for the function. Since in python I can't pin the output variable to a specific type, I tried to resolve the ambiguity with:

a = Variable.Constant[System.Double](System.Array[System.Double]([1.0, 2.0, 3.0]))

but then I get the exception:

TypeError: No method matches given arguments for Constant

I also tried:

a = Variable.Constant.Overloads[System.Double](System.Array[System.Double]([1.0, 2.0, 3.0]))

but then I get the exception:

TypeError: No match found for signature

It seems that there is pull-request (#227) ongoing, but it looks to have been work in progress for quite a while now. Is this is not priority, is there a workaround that I can try?

Tobimaru avatar Mar 02 '19 17:03 Tobimaru

The method overload resolution of Python.NET is very tricky to get right, as we're dealing with two different type systems that should somehow be made compatible. I'm not sure how #227 would solve this.

filmor avatar Mar 06 '19 15:03 filmor

Is there any way to work around this problem? The only thing I can think of is to write a small C# library that explicitly instantiates the generic methods with the types that I need. I hope that python.NET can then resolve the overloads.

Tobimaru avatar Mar 07 '19 21:03 Tobimaru

Yes, that approach works fine, and I'm currently not aware of a workaround that doesn't require an additional library.

filmor avatar Mar 08 '19 06:03 filmor

You can always use reflection, search this issue tracker or stackoverflow "python.net" tag.

den-run-ai avatar Mar 08 '19 12:03 den-run-ai

Sorry for the late response. Thanks for the info. I tried with a wrapper library around the generic methods and that seems to work. But now I'm having issues with [] overloads. I haven't tried with using reflections yet, I'll give it a try.

Tobimaru avatar Mar 20 '19 09:03 Tobimaru

Reflection doesn't seem to work either. The problem is that in the module that I'm trying to use (infer.net), Variable is an abstract class and Constant is a static method of this abstract class. I don't know how to invoke the method of an abstract class. If I do:

var_type = dll.GetType("Variable")
method = var_type.GetMethod("Constant")

Then I get the error:

AttributeError: 'NoneType' object has no attribute 'GetMethod'

Tobimaru avatar Mar 23 '19 16:03 Tobimaru

This is probably too late but an infer.net-specific workaround could be to use Invoker.InvokeStatic(Variable, "Constant", args) e.g. https://github.com/dotnet/infer/blob/0c75b5ef4190c5eee55e663741e645cb997b7236/test/TestPython/test_tutorials.py#L217

christabella avatar Jan 13 '21 13:01 christabella