Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C# code from python using pythonnet

Following is the C# code. How do I call the GenericMethod() inside the NonGenericClass from Python using pythonnet?

namespace CSharpTestCode
{
    public interface Person
    {
    }

    public class Employee : Person
    {
    }

    public class TempGenericClass<T>
    {
    }

    public class NonGenericClass
    {
        public static T GenericMethod<T>(TempGenericClass<T> tempGeneric) where T : class, Person
        {
            return null;
        }
    }
}

Python code that I tried:

import clr
clr.AddReference(r'\Documents\visual studio 2015\Projects\SamplePythonApp\CSharpTestCode\bin\Debug\CSharpTestCode.dll')
from CSharpTestCode import *

genericMethod = NonGenericClass.GenericMethod(TempGenericClass[Employee]())

Error that I got:

Unhandled Exception: System.ArgumentException: GenericArguments[0], 'CSharpTestCode.TempGenericClass`1[CSharpTestCode.Employee]', on 'T GenericMethod[T](CSharpTestCode.TempGenericClass`1[T])' violates the constraint of type 'T'. ---> System.Security.VerificationException: Method CSharpTestCode.NonGenericClass.GenericMethod: type argument 'CSharpTestCode.TempGenericClass`1[CSharpTestCode.Employee]' violates the constraint of type parameter 'T'.
   at System.RuntimeMethodHandle.GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation)
   at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
   --- End of inner exception stack trace ---
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.Reflection.RuntimeMethodInfo.MakeGenericMethod(Type[] methodInstantiation)
   at Python.Runtime.MethodBinder.MatchParameters(MethodInfo[] mi, Type[] tp)
   at Python.Runtime.MethodBinder.Bind(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
   at Python.Runtime.MethodBinder.Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info, MethodInfo[] methodinfo)
   at Python.Runtime.MethodObject.Invoke(IntPtr target, IntPtr args, IntPtr kw, MethodBase info)
   at Python.Runtime.MethodBinding.tp_call(IntPtr ob, IntPtr args, IntPtr kw)
like image 226
Developer Avatar asked Oct 29 '22 04:10

Developer


1 Answers

I should admit that pythonnet is not supposed to crash CPython interpreter even on this bad example of generic call with invalid arguments to the method.

Here is how to properly make your generic calls with pythonnet, notice how passing wrong types fails properly:

In [3]: NonGenericClass.GenericMethod[Person](TempGenericClass[Person]())


In [4]: NonGenericClass.GenericMethod[Employee](TempGenericClass[Employee]())


In [5]: NonGenericClass.GenericMethod[Person](TempGenericClass[Employee]())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-d13751f7586f> in <module>()
----> 1 NonGenericClass.GenericMethod[Person](TempGenericClass[Employee]())

TypeError: No method matches given arguments


In [6]: NonGenericClass.GenericMethod[Employee](TempGenericClass[Person]())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-04c3c0db6c6b> in <module>()
----> 1 NonGenericClass.GenericMethod[Employee](TempGenericClass[Person]())

TypeError: No method matches given arguments
like image 122
denfromufa Avatar answered Nov 12 '22 22:11

denfromufa