Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcfe1585

Browse files
authored
Merge pull request#1998 from filmor/fix-derived-generic-interface
Fix implementing a generic interface with a Python class
2 parentscc364c3 +5c1e02f commitcfe1585

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

‎src/runtime/Types/ClassDerived.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ private static void AddVirtualMethod(MethodInfo method, Type baseType, TypeBuild
436436
il.Emit(OpCodes.Ldloc_0);
437437

438438
il.Emit(OpCodes.Ldtoken,method);
439+
il.Emit(OpCodes.Ldtoken,method.DeclaringType);
439440
#pragma warning disableCS0618// PythonDerivedType is for internal use only
440441
if(method.ReturnType==typeof(void))
441442
{
@@ -505,6 +506,7 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
505506

506507
il.DeclareLocal(typeof(object[]));
507508
il.DeclareLocal(typeof(RuntimeMethodHandle));
509+
il.DeclareLocal(typeof(RuntimeTypeHandle));
508510

509511
// this
510512
il.Emit(OpCodes.Ldarg_0);
@@ -546,6 +548,11 @@ private static void AddPythonMethod(string methodName, PyObject func, TypeBuilde
546548
il.Emit(OpCodes.Ldloca_S,1);
547549
il.Emit(OpCodes.Initobj,typeof(RuntimeMethodHandle));
548550
il.Emit(OpCodes.Ldloc_1);
551+
552+
// type handle is also not required
553+
il.Emit(OpCodes.Ldloca_S,2);
554+
il.Emit(OpCodes.Initobj,typeof(RuntimeTypeHandle));
555+
il.Emit(OpCodes.Ldloc_2);
549556
#pragma warning disableCS0618// PythonDerivedType is for internal use only
550557

551558
// invoke the method
@@ -698,7 +705,7 @@ public class PythonDerivedType
698705
/// class) it calls it, otherwise it calls the base method.
699706
/// </summary>
700707
publicstaticT?InvokeMethod<T>(IPythonDerivedTypeobj,stringmethodName,stringorigMethodName,
701-
object[]args,RuntimeMethodHandlemethodHandle)
708+
object[]args,RuntimeMethodHandlemethodHandle,RuntimeTypeHandledeclaringTypeHandle)
702709
{
703710
varself=GetPyObj(obj);
704711

@@ -724,7 +731,10 @@ public class PythonDerivedType
724731
}
725732

726733
PyObjectpy_result=method.Invoke(pyargs);
727-
PyTuple?result_tuple=MarshalByRefsBack(args,methodHandle,py_result,outsOffset:1);
734+
varclrMethod=methodHandle!=default
735+
?MethodBase.GetMethodFromHandle(methodHandle,declaringTypeHandle)
736+
:null;
737+
PyTuple?result_tuple=MarshalByRefsBack(args,clrMethod,py_result,outsOffset:1);
728738
returnresult_tupleis notnull
729739
?result_tuple[0].As<T>()
730740
:py_result.As<T>();
@@ -754,7 +764,7 @@ public class PythonDerivedType
754764
}
755765

756766
publicstaticvoidInvokeMethodVoid(IPythonDerivedTypeobj,stringmethodName,stringorigMethodName,
757-
object?[]args,RuntimeMethodHandlemethodHandle)
767+
object?[]args,RuntimeMethodHandlemethodHandle,RuntimeTypeHandledeclaringTypeHandle)
758768
{
759769
varself=GetPyObj(obj);
760770
if(null!=self.Ref)
@@ -779,7 +789,10 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
779789
}
780790

781791
PyObjectpy_result=method.Invoke(pyargs);
782-
MarshalByRefsBack(args,methodHandle,py_result,outsOffset:0);
792+
varclrMethod=methodHandle!=default
793+
?MethodBase.GetMethodFromHandle(methodHandle,declaringTypeHandle)
794+
:null;
795+
MarshalByRefsBack(args,clrMethod,py_result,outsOffset:0);
783796
return;
784797
}
785798
}
@@ -811,12 +824,11 @@ public static void InvokeMethodVoid(IPythonDerivedType obj, string methodName, s
811824
/// as a tuple of new values for those arguments, and updates corresponding
812825
/// elements of <paramref name="args"/> array.
813826
/// </summary>
814-
privatestaticPyTuple?MarshalByRefsBack(object?[]args,RuntimeMethodHandlemethodHandle,PyObjectpyResult,intoutsOffset)
827+
privatestaticPyTuple?MarshalByRefsBack(object?[]args,MethodBase?method,PyObjectpyResult,intoutsOffset)
815828
{
816-
if(methodHandle==default)returnnull;
829+
if(methodisnull)returnnull;
817830

818-
varoriginalMethod=MethodBase.GetMethodFromHandle(methodHandle);
819-
varparameters=originalMethod.GetParameters();
831+
varparameters=method.GetParameters();
820832
PyTuple?outs=null;
821833
intbyrefIndex=0;
822834
for(inti=0;i<parameters.Length;++i)

‎src/testing/interfacetest.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private interface IPrivate
7979
{
8080
}
8181
}
82-
82+
8383
publicinterfaceIOutArg
8484
{
8585
stringMyMethod_Out(stringname,outintindex);
@@ -93,4 +93,25 @@ public static int CallMyMethod_Out(IOutArg myInterface)
9393
returnindex;
9494
}
9595
}
96+
97+
publicinterfaceIGenericInterface<T>
98+
{
99+
publicTGet(Tx);
100+
}
101+
102+
publicclassSpecificInterfaceUser
103+
{
104+
publicSpecificInterfaceUser(IGenericInterface<int>some,intx)
105+
{
106+
some.Get(x);
107+
}
108+
}
109+
110+
publicclassGenericInterfaceUser<T>
111+
{
112+
publicGenericInterfaceUser(IGenericInterface<T>some,Tx)
113+
{
114+
some.Get(x);
115+
}
116+
}
96117
}

‎tests/test_subclass.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
importSystem
1010
importpytest
1111
fromPython.Testimport (IInterfaceTest,SubClassTest,EventArgsTest,
12-
FunctionsTest)
12+
FunctionsTest,IGenericInterface)
1313
fromSystem.Collections.GenericimportList
1414

1515

@@ -29,6 +29,17 @@ def bar(self, x, i):
2929
returnInterfaceTestClass
3030

3131

32+
definterface_generic_class_fixture(subnamespace):
33+
34+
classGenericInterfaceImpl(IGenericInterface[int]):
35+
__namespace__="Python.Test."+subnamespace
36+
37+
defGet(self,x):
38+
returnx
39+
40+
returnGenericInterfaceImpl
41+
42+
3243
defderived_class_fixture(subnamespace):
3344
"""Delay creation of class until test starts."""
3445

@@ -306,3 +317,13 @@ class Derived(BaseClass):
306317

307318
importgc
308319
gc.collect()
320+
321+
deftest_generic_interface():
322+
fromSystemimportInt32
323+
fromPython.TestimportGenericInterfaceUser,SpecificInterfaceUser
324+
325+
GenericInterfaceImpl=interface_generic_class_fixture(test_generic_interface.__name__)
326+
327+
obj=GenericInterfaceImpl()
328+
SpecificInterfaceUser(obj,Int32(0))
329+
GenericInterfaceUser[Int32](obj,Int32(0))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp