8000 Fixed #296 Converter support for PyObject (#297) · pythonnet/pythonnet@566898a · GitHub
[go: up one dir, main page]

Skip to content

Commit 566898a

Browse files
rmadsen-ksdenfromufa
authored andcommitted
Fixed #296 Converter support for PyObject (#297)
* Fixed #296 * Added test for #296 * removed windows line endings * Fixed comment and removed \r from added source
1 parent 66d755f commit 566898a

File tree

4 files changed

+52
-0
lines changed

4 files changed

+52
-0
lines changed

src/runtime/converter.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ internal static IntPtr ToPython<T>(T value)
126126

127127
internal static IntPtr ToPython(Object value, Type type)
128128
{
129+
if(value is PyObject)
130+
{
131+
IntPtr handle = ((PyObject)value).Handle;
132+
Runtime.XIncref(handle);
133+
return handle;
134+
}
129135
IntPtr result = IntPtr.Zero;
130136

131137
// Null always converts to None in Python.
@@ -265,6 +271,13 @@ internal static bool ToManaged(IntPtr value, Type type,
265271
internal static bool ToManagedValue(IntPtr value, Type obType,
266272
out Object result, bool setError)
267273
{
274+
if (obType == typeof(PyObject))
275+
{
276+
Runtime.XIncref(value); // PyObject() assumes ownership
277+
result = new PyObject(value);
278+
return true;
279+
}
280+
268281
// Common case: if the Python value is a wrapped managed object
269282
// instance, just return the wrapped object.
270283
ManagedType mt = ManagedType.GetManagedObject(value);

src/runtime/pyobject.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ protected virtual void Dispose(bool disposing)
127127
}
128128
}
129129

130+
public long RefCount
131+
{
132+
get
133+
{
134+
if(!disposed)
135+
return Runtime.Refcount(obj);
136+
return -1;
137+
}
138+
}
139+
130140
public void Dispose()
131141
{
132142
Dispose(true);

src/testing/callbacktest.cs

Lines changed: 14 additions & 0 deletions
8000
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,18 @@ public string Call_simpleDefaultArg_WithEmptyArgs(string moduleName)
2828
}
2929
}
3030
}
31+
32+
//==========================================================================
33+
// Tests calling from Python into C# and back into Python using a PyObject.
34+
// SelfCallbackTest should be inherited by a Python class.
35+
// Used in test_class.py / testCallback
36+
//==========================================================================
37+
public class SelfCallbackTest
38+
{
39+
public void Callback(Runtime.PyObject self)
40+
{
41+
using (Runtime.Py.GIL())
42+
((dynamic)self).PyCallback(self);
43+
}
44+
}
3145
}

src/tests/test_class.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,21 @@ def testComparisons(self):
250250
c2 = ClassTest()
251251
self.assertRaises(TypeError, lambda: c1 < c2)
252252

253+
def testSelfCallback(self):
254+
""" Test calling back and forth between this and a c# baseclass."""
255+
class CallbackUser(Test.SelfCallbackTest):
256+
def DoCallback(self):
257+
self.PyCallbackWasCalled = False
258+
self.SameReference = False
259+
return self.Callback(self)
260+
def PyCallback(self, self2):
261+
self.PyCallbackWasCalled = True
262+
self.SameReference = self == self2
263+
264+
testobj = CallbackUser()
265+
testobj.DoCallback()
266+
self.assertTrue(testobj.PyCallbackWasCalled)
267+
self.assertTrue(testobj.SameReference)
253268

254269
class ClassicClass:
255270
def kind(self):

0 commit comments

Comments
 (0)
0