| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent d44f1da commit 1dd36ae
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -173,6 +173,12 @@ internal static IntPtr ToPython(object value, Type type) | |||
| 173 | 173 | } | |
| 174 | 174 | } | |
| 175 | 175 | ||
| 176 | + if (type.IsInterface) | ||
| 177 | + { | ||
| 178 | + var ifaceObj = (InterfaceObject)ClassManager.GetClass(type); | ||
| 179 | + return CLRObject.GetInstHandle(value, ifaceObj.pyHandle); | ||
| 180 | + } | ||
| 181 | + | ||
| 176 | 182 | // it the type is a python subclass of a managed type then return the | |
| 177 | 183 | // underlying python object rather than construct a new wrapper object. | |
| 178 | 184 | var pyderived = value as IPythonDerivedType; | |
@@ -182,6 +188,7 @@ internal static IntPtr ToPython(object value, Type type) | |||
| 182 | 188 | return ClassDerivedObject.ToPython(pyderived); | |
| 183 | 189 | } | |
| 184 | 190 | ||
| 191 | + | ||
| 185 | 192 | // hmm - from Python, we almost never care what the declared | |
| 186 | 193 | // type is. we'd rather have the object bound to the actual | |
| 187 | 194 | // implementing class. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -744,7 +744,7 @@ internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw, MethodBase i | |||
| 744 | 744 | Type pt = pi[i].ParameterType; | |
| 745 | 745 | if (pi[i].IsOut || pt.IsByRef) | |
| 746 | 746 | { | |
| 747 | - v = Converter.ToPython(binding.args[i], pt); | ||
| 747 | + v = Converter.ToPython(binding.args[i], pt.GetElementType()); | ||
| 748 | 748 | Runtime.PyTuple_SetItem(t, n, v); | |
| 749 | 749 | n++; | |
| 750 | 750 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -164,13 +164,13 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) | |||
| 164 | 164 | // we want to do this after the slot stuff above in case the class itself implements a slot method | |
| 165 | 165 | InitializeSlots(type, impl.GetType()); | |
| 166 | 166 | ||
| 167 | - if (!clrType.GetInterfaces().Any(ifc => ifc == typeof(IEnumerable) || ifc == typeof(IEnumerator))) | ||
| 167 | + if (!typeof(IEnumerable).IsAssignableFrom(clrType) && | ||
| 168 | + !typeof(IEnumerator).IsAssignableFrom(clrType)) | ||
| 168 | 169 | { | |
| 169 | 170 | // The tp_iter slot should only be set for enumerable types. | |
| 170 | 171 | Marshal.WriteIntPtr(type, TypeOffset.tp_iter, IntPtr.Zero); | |
| 171 | 172 | } | |
| 172 | 173 | ||
| 173 | - | ||
| 174 | 174 | if (base_ != IntPtr.Zero) | |
| 175 | 175 | { | |
| 176 | 176 | Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11,7 +11,6 @@ internal interface IInternalInterface | |||
| 11 | 11 | { | |
| 12 | 12 | } | |
| 13 | 13 | ||
| 14 | - | ||
| 15 | 14 | public interface ISayHello1 | |
| 16 | 15 | { | |
| 17 | 16 | string SayHello(); | |
@@ -43,6 +42,22 @@ string ISayHello2.SayHello() | |||
| 43 | 42 | return "hello 2"; | |
| 44 | 43 | } | |
| 45 | 44 | ||
| 45 | + public ISayHello1 GetISayHello1() | ||
| 46 | + { | ||
| 47 | + return this; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public void GetISayHello2(out ISayHello2 hello2) | ||
| 51 | + { | ||
| 52 | + hello2 = this; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public ISayHello1 GetNoSayHello(out ISayHello2 hello2) | ||
| 56 | + { | ||
| 57 | + hello2 = null; | ||
| 58 | + return null; | ||
| 59 | + } | ||
| 60 | + | ||
| 46 | 61 | public interface IPublic | |
| 47 | 62 | { | |
| 48 | 63 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -89,13 +89,24 @@ public static string test_bar(IInterfaceTest x, string s, int i) | |||
| 89 | 89 | } | |
| 90 | 90 | ||
| 91 | 91 | // test instances can be constructed in managed code | |
| 92 | - public static IInterfaceTest create_instance(Type t) | ||
| 92 | + public static SubClassTest create_instance(Type t) | ||
| 93 | + { | ||
| 94 | + return (SubClassTest)t.GetConstructor(new Type[] { }).Invoke(new object[] { }); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public static IInterfaceTest create_instance_interface(Type t) | ||
| 93 | 98 | { | |
| 94 | 99 | return (IInterfaceTest)t.GetConstructor(new Type[] { }).Invoke(new object[] { }); | |
| 95 | 100 | } | |
| 96 | 101 | ||
| 97 | - // test instances pass through managed code unchanged | ||
| 98 | - public static IInterfaceTest pass_through(IInterfaceTest s) | ||
| 102 | + // test instances pass through managed code unchanged ... | ||
| 103 | + public static SubClassTest pass_through(SubClassTest s) | ||
| 104 | + { | ||
| 105 | + return s; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + // ... but the return type is an interface type, objects get wrapped | ||
| 109 | + public static IInterfaceTest pass_through_interface(IInterfaceTest s) | ||
| 99 | 110 | { | |
| 100 | 111 | return s; | |
| 101 | 112 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1288,9 +1288,10 @@ def test_special_array_creation(): | |||
| 1288 | 1288 | assert value[1].__class__ == inst.__class__ | |
| 1289 | 1289 | assert value.Length == 2 | |
| 1290 | 1290 | ||
| 1291 | + iface_class = ISayHello1(inst).__class__ | ||
| 1291 | 1292 | value = Array[ISayHello1]([inst, inst]) | |
| 1292 | - assert value[0].__class__ == inst.__class__ | ||
| 1293 | - assert value[1].__class__ == inst.__class__ | ||
| 1293 | + assert value[0].__class__ == iface_class | ||
| 1294 | + assert value[1].__class__ == iface_class | ||
| 1294 | 1295 | assert value.Length == 2 | |
| 1295 | 1296 | ||
| 1296 | 1297 | inst = System.Exception("badness") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -319,7 +319,6 @@ def test_generic_method_type_handling(): | |||
| 319 | 319 | assert_generic_method_by_type(ShortEnum, ShortEnum.Zero) | |
| 320 | 320 | assert_generic_method_by_type(System.Object, InterfaceTest()) | |
| 321 | 321 | assert_generic_method_by_type(InterfaceTest, InterfaceTest(), 1) | |
| 322 | - assert_generic_method_by_type(ISayHello1, InterfaceTest(), 1) | ||
| 323 | 322 | ||
| 324 | 323 | ||
| 325 | 324 | def test_correct_overload_selection(): | |
@@ -548,10 +547,11 @@ def test_method_overload_selection_with_generic_types(): | |||
| 548 | 547 | value = MethodTest.Overloaded.__overloads__[vtype](input_) | |
| 549 | 548 | assert value.value.__class__ == inst.__class__ | |
| 550 | 549 | ||
| 550 | + iface_class = ISayHello1(inst).__class__ | ||
| 551 | 551 | vtype = GenericWrapper[ISayHello1] | |
| 552 | 552 | input_ = vtype(inst) | |
| 553 | 553 | value = MethodTest.Overloaded.__overloads__[vtype](input_) | |
| 554 | - assert value.value.__class__ == inst.__class__ | ||
| 554 | + assert value.value.__class__ == iface_class | ||
| 555 | 555 | ||
| 556 | 556 | vtype = System.Array[GenericWrapper[int]] | |
| 557 | 557 | input_ = vtype([GenericWrapper[int](0), GenericWrapper[int](1)]) | |
@@ -726,11 +726,12 @@ def test_overload_selection_with_arrays_of_generic_types(): | |||
| 726 | 726 | assert value[0].value.__class__ == inst.__class__ | |
| 727 | 727 | assert value.Length == 2 | |
| 728 | 728 | ||
| 729 | + iface_class = ISayHello1(inst).__class__ | ||
| 729 | 730 | gtype = GenericWrapper[ISayHello1] | |
| 730 | 731 | vtype = System.Array[gtype] | |
| 731 | 732 | input_ = vtype([gtype(inst), gtype(inst)]) | |
| 732 | 733 | value = MethodTest.Overloaded.__overloads__[vtype](input_) | |
| 733 | - assert value[0].value.__class__ == inst.__class__ | ||
| 734 | + assert value[0].value.__class__ == iface_class | ||
| 734 | 735 | assert value.Length == 2 | |
| 735 | 736 | ||
| 736 | 737 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -67,3 +67,35 @@ def test_explicit_cast_to_interface(): | |||
| 67 | 67 | assert i2.SayHello() == 'hello 2' | |
| 68 | 68 | assert hasattr(i2, 'SayHello') | |
| 69 | 69 | assert not hasattr(i2, 'HelloProperty') | |
| 70 | + | ||
| 71 | + | ||
| 72 | + def test_interface_object_returned_through_method(): | ||
| 73 | + """Test interface type is used if method return type is interface""" | ||
| 74 | + from Python.Test import InterfaceTest | ||
| 75 | + | ||
| 76 | + ob = InterfaceTest() | ||
| 77 | + hello1 = ob.GetISayHello1() | ||
| 78 | + assert type(hello1).__name__ == 'ISayHello1' | ||
| 79 | + | ||
| 80 | + assert hello1.SayHello() == 'hello 1' | ||
| 81 | + | ||
| 82 | + | ||
| 83 | + def test_interface_object_returned_through_out_param(): | ||
| 84 | + """Test interface type is used for out parameters of interface types""" | ||
| 85 | + from Python.Test import InterfaceTest | ||
| 86 | + | ||
| 87 | + ob = InterfaceTest() | ||
| 88 | + hello2 = ob.GetISayHello2(None) | ||
| 89 | + assert type(hello2).__name__ == 'ISayHello2' | ||
| 90 | + | ||
| 91 | + assert hello2.SayHello() == 'hello 2' | ||
| 92 | + | ||
| 93 | + | ||
| 94 | + def test_null_interface_object_returned(): | ||
| 95 | + """Test None is used also for methods with interface return types""" | ||
| 96 | + from Python.Test import InterfaceTest | ||
| 97 | + | ||
| 98 | + ob = InterfaceTest() | ||
| 99 | + hello1, hello2 = ob.GetNoSayHello(None) | ||
| 100 | + assert hello1 is None | ||
| 101 | + assert hello2 is None | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -564,8 +564,10 @@ def test_explicit_overload_selection(): | |||
| 564 | 564 | value = MethodTest.Overloaded.__overloads__[InterfaceTest](inst) | |
| 565 | 565 | assert value.__class__ == inst.__class__ | |
| 566 | 566 | ||
| 567 | + iface_class = ISayHello1(InterfaceTest()).__class__ | ||
| 567 | 568 | value = MethodTest.Overloaded.__overloads__[ISayHello1](inst) | |
| 568 | - assert value.__class__ == inst.__class__ | ||
| 569 | + assert value.__class__ != inst.__class__ | ||
| 570 | + assert value.__class__ == iface_class | ||
| 569 | 571 | ||
| 570 | 572 | atype = Array[System.Object] | |
| 571 | 573 | value = MethodTest.Overloaded.__overloads__[str, int, atype]( | |
@@ -718,11 +720,12 @@ def test_overload_selection_with_array_types(): | |||
| 718 | 720 | assert value[0].__class__ == inst.__class__ | |
| 719 | 721 | assert value[1].__class__ == inst.__class__ | |
| 720 | 722 | ||
| 723 | + iface_class = ISayHello1(inst).__class__ | ||
| 721 | 724 | vtype = Array[ISayHello1] | |
| 722 | 725 | input_ = vtype([inst, inst]) | |
| 723 | 726 | value = MethodTest.Overloaded.__overloads__[vtype](input_) | |
| 724 | - assert value[0].__class__ == inst.__class__ | ||
| 725 | - assert value[1].__class__ == inst.__class__ | ||
| 727 | + assert value[0].__class__ == iface_class | ||
| 728 | + assert value[1].__class__ == iface_class | ||
| 726 | 729 | ||
| 727 | 730 | ||
| 728 | 731 | def test_explicit_overload_selection_failure(): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -104,8 +104,10 @@ def test_interface(): | |||
| 104 | 104 | assert ob.bar("bar", 2) == "bar/bar" | |
| 105 | 105 | assert FunctionsTest.test_bar(ob, "bar", 2) == "bar/bar" | |
| 106 | 106 | ||
| 107 | - x = FunctionsTest.pass_through(ob) | ||
| 108 | - assert id(x) == id(ob) | ||
| 107 | + # pass_through will convert from InterfaceTestClass -> IInterfaceTest, | ||
| 108 | + # causing a new wrapper object to be created. Hence id will differ. | ||
| 109 | + x = FunctionsTest.pass_through_interface(ob) | ||
| 110 | + assert id(x) != id(ob) | ||
| 109 | 111 | ||
| 110 | 112 | ||
| 111 | 113 | def test_derived_class(): | |
@@ -173,14 +175,14 @@ def test_create_instance(): | |||
| 173 | 175 | assert id(x) == id(ob) | |
| 174 | 176 | ||
| 175 | 177 | InterfaceTestClass = interface_test_class_fixture(test_create_instance.__name__) | |
| 176 | - ob2 = FunctionsTest.create_instance(InterfaceTestClass) | ||
| 178 | + ob2 = FunctionsTest.create_instance_interface(InterfaceTestClass) | ||
| 177 | 179 | assert ob2.foo() == "InterfaceTestClass" | |
| 178 | 180 | assert FunctionsTest.test_foo(ob2) == "InterfaceTestClass" | |
| 179 | 181 | assert ob2.bar("bar", 2) == "bar/bar" | |
| 180 | 182 | assert FunctionsTest.test_bar(ob2, "bar", 2) == "bar/bar" | |
| 181 | 183 | ||
| 182 | - y = FunctionsTest.pass_through(ob2) | ||
| 183 | - assert id(y) == id(ob2) | ||
| 184 | + y = FunctionsTest.pass_through_interface(ob2) | ||
| 185 | + assert id(y) != id(ob2) | ||
| 184 | 186 | ||
| 185 | 187 | ||
| 186 | 188 | def test_events(): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments