10000 Add properties for accessing the object implementing an interface · pythonnet/pythonnet@119326f · GitHub
[go: up one dir, main page]

Skip to content

Commit 119326f

Browse files
committed
Add properties for accessing the object implementing an interface
1 parent 06e311c commit 119326f

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

src/runtime/converter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ internal static IntPtr ToPython(object value, Type type)
176176
if (type.IsInterface)
177177
{
178178
var ifaceObj = (InterfaceObject)ClassManager.GetClass(type);
179-
return CLRObject.GetInstHandle(value, ifaceObj.pyHandle);
179+
return ifaceObj.WrapObject(value);
180180
}
181181

182182
// We need to special case interface array handling to ensure we

src/runtime/interfaceobject.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,21 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
7171
return IntPtr.Zero;
7272
}
7373

74-
return CLRObject.GetInstHandle(obj, self.pyHandle);
74+
return self.WrapObject(obj);
75+
}
76+
77+
/// <summary>
78+
/// Wrap the given object in an interface object, so that only methods
79+
/// of the interface are available. The wrapped object is available
80+
/// through properties in both converted/encoded (__implementation__)
81+
/// and raw form (__raw_implementation__).
82+
/// </summary>
83+
public IntPtr WrapObject(object impl)
84+
{
85+
var objPtr = CLRObject.GetInstHandle(impl, pyHandle);
86+
Runtime.PyObject_SetAttrString(objPtr, "__implementation__", Converter.ToPython(impl));
87+
Runtime.PyObject_SetAttrString(objPtr, "__raw_implementation__", CLRObject.GetInstHandle(impl));
88+
return objPtr;
7589
}
7690
}
7791
}

src/tests/test_interface.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ def test_explicit_cast_to_interface():
6161
assert hasattr(i1, 'SayHello')
6262
assert i1.SayHello() == 'hello 1'
6363
assert not hasattr(i1, 'HelloProperty')
64+
assert i1.__implementation__ == ob
65+
assert i1.__raw_implementation__ == ob
6466

6567
i2 = Test.ISayHello2(ob)
6668
assert type(i2).__name__ == 'ISayHello2'
@@ -76,6 +78,7 @@ def test_interface_object_returned_through_method():
7678
ob = InterfaceTest()
7779
hello1 = ob.GetISayHello1()
7880
assert type(hello1).__name__ == 'ISayHello1'
81+
assert hello1.__implementation__.__class__.__name__ == "InterfaceTest"
7982

8083
assert hello1.SayHello() == 'hello 1'
8184

@@ -107,3 +110,13 @@ def test_interface_array_returned():
107110
ob = InterfaceTest()
108111
hellos = ob.GetISayHello1Array()
109112
assert type(hellos[0]).__name__ == 'ISayHello1'
113+
assert hellos[0].__implementation__.__class__.__name__ == "InterfaceTest"
114+
115+
def test_implementation_access():
116+
"""Test the __implementation__ and __raw_implementation__ properties"""
117+
import System
118+
clrVal = System.Int32(100)
119+
i = System.IComparable(clrVal)
120+
assert 100 == i.__implementation__
121+
assert clrVal == i.__raw_implementation__
122+
assert i.__implementation__ != i.__raw_implementation__

0 commit comments

Comments
 (0)
0