From 7d132c9af495401497fdee0c3b39dfceaae7e9ea Mon Sep 17 00:00:00 2001 From: Rolf Madsen Date: Tue, 29 Nov 2016 15:36:21 +0100 Subject: [PATCH 1/4] Fixed #296 --- src/runtime/converter.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index ef3aa3e18..3071e8b34 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -126,6 +126,12 @@ internal static IntPtr ToPython(T value) internal static IntPtr ToPython(Object value, Type type) { + if(value is PyObject) + { + IntPtr handle = ((PyObject)value).Handle; + Runtime.XIncref(handle); + return handle; + } IntPtr result = IntPtr.Zero; // Null always converts to None in Python. @@ -265,8 +271,15 @@ internal static bool ToManaged(IntPtr value, Type type, internal static bool ToManagedValue(IntPtr value, Type obType, out Object result, bool setError) { - // Common case: if the Python value is a wrapped managed object - // instance, just return the wrapped object. + if (obType == typeof(PyObject)) + { + Runtime.XIncref(value); // PyObject() assumes ownership + result = new PyObject(value); + return true; + } + + // Common case: if the Python value is a wrapped managed object + // instance, just return the wrapped object. ManagedType mt = ManagedType.GetManagedObject(value); result = null; From bb73ed1600f8b9d9b5850bf45a0292382a10c703 Mon Sep 17 00:00:00 2001 From: Rolf Madsen Date: Wed, 30 Nov 2016 09:15:07 +0100 Subject: [PATCH 2/4] Added test for #296 --- src/testing/callbacktest.cs | 14 ++++++++++++++ src/tests/test_class.py | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/testing/callbacktest.cs b/src/testing/callbacktest.cs index 81389289d..f4b3444a4 100644 --- a/src/testing/callbacktest.cs +++ b/src/testing/callbacktest.cs @@ -27,5 +27,19 @@ public string Call_simpleDefaultArg_WithEmptyArgs(string moduleName) return module.simpleDefaultArg(); } } + } + + //========================================================================== + // Tests calling from Python into C# and back into Python using a PyObject. + // SelfCallbackTest should be inherited from a Python class. + // Used in test_class.py / testCallback + //========================================================================== + public class SelfCallbackTest + { + public void Callback(Runtime.PyObject self) + { + using (Runtime.Py.GIL()) + ((dynamic)self).PyCallback(self); + } } } diff --git a/src/tests/test_class.py b/src/tests/test_class.py index fe8fc982b..a0cb92cc6 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -4,6 +4,7 @@ import Python.Test as Test import System import six +import Python.Runtime if six.PY3: DictProxyType = type(object.__dict__) @@ -198,6 +199,21 @@ def __setitem__(self, key, value): self.assertTrue(table.Count == 3) + def testSelfCallback(self): + """ Test calling back and forth between this and a c# baseclass.""" + class CallbackUser(Test.SelfCallbackTest): + def DoCallback(self): + self.PyCallbackWasCalled = False + self.SameReference = False + return self.Callback(self) + def PyCallback(self, self2): + self.PyCallbackWasCalled = True + self.SameReference = self == self2 + + testobj = CallbackUser() + testobj.DoCallback() + self.assertTrue(testobj.PyCallbackWasCalled) + self.assertTrue(testobj.SameReference) class ClassicClass: def kind(self): From d5951f693f92be2567cff0199aa9fb68eb20c620 Mon Sep 17 00:00:00 2001 From: Rolf Madsen Date: Thu, 1 Dec 2016 09:22:12 +0100 Subject: [PATCH 3/4] removed windows line endings --- src/tests/test_class.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/test_class.py b/src/tests/test_class.py index d355d4802..9e2af14da 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -6,7 +6,7 @@ import System import six from Python.Test import ClassTest -from System.Collections import Hashtable +from System.Collections import Hashtable if six.PY3: DictProxyType = type(object.__dict__) @@ -264,7 +264,7 @@ def PyCallback(self, self2): testobj = CallbackUser() testobj.DoCallback() self.assertTrue(testobj.PyCallbackWasCalled) - self.assertTrue(testobj.SameReference) + self.assertTrue(testobj.SameReference) class ClassicClass: def kind(self): From 335cd37c54a2837e677ed8e1a671300b2231ce2b Mon Sep 17 00:00:00 2001 From: Rolf Madsen Date: Mon, 5 Dec 2016 10:37:53 +0100 Subject: [PATCH 4/4] Fixed comment and removed \r from added source --- src/runtime/converter.cs | 28 ++++++++++++++-------------- src/runtime/pyobject.cs | 10 ++++++++++ src/testing/callbacktest.cs | 28 ++++++++++++++-------------- 3 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 3071e8b34..1170efe7a 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -126,11 +126,11 @@ internal static IntPtr ToPython(T value) internal static IntPtr ToPython(Object value, Type type) { - if(value is PyObject) - { - IntPtr handle = ((PyObject)value).Handle; - Runtime.XIncref(handle); - return handle; + if(value is PyObject) + { + IntPtr handle = ((PyObject)value).Handle; + Runtime.XIncref(handle); + return handle; } IntPtr result = IntPtr.Zero; @@ -271,15 +271,15 @@ internal static bool ToManaged(IntPtr value, Type type, internal static bool ToManagedValue(IntPtr value, Type obType, out Object result, bool setError) { - if (obType == typeof(PyObject)) - { - Runtime.XIncref(value); // PyObject() assumes ownership - result = new PyObject(value); - return true; - } - - // Common case: if the Python value is a wrapped managed object - // instance, just return the wrapped object. + if (obType == typeof(PyObject)) + { + Runtime.XIncref(value); // PyObject() assumes ownership + result = new PyObject(value); + return true; + } + + // Common case: if the Python value is a wrapped managed object + // instance, just return the wrapped object. ManagedType mt = ManagedType.GetManagedObject(value); result = null; diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index 323d50da7..ba44c0c21 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -127,6 +127,16 @@ protected virtual void Dispose(bool disposing) } } + public long RefCount + { + get + { + if(!disposed) + return Runtime.Refcount(obj); + return -1; + } + } + public void Dispose() { Dispose(true); diff --git a/src/testing/callbacktest.cs b/src/testing/callbacktest.cs index f4b3444a4..70c7bbc9e 100644 --- a/src/testing/callbacktest.cs +++ b/src/testing/callbacktest.cs @@ -27,19 +27,19 @@ public string Call_simpleDefaultArg_WithEmptyArgs(string moduleName) return module.simpleDefaultArg(); } } - } - - //========================================================================== - // Tests calling from Python into C# and back into Python using a PyObject. - // SelfCallbackTest should be inherited from a Python class. - // Used in test_class.py / testCallback - //========================================================================== - public class SelfCallbackTest - { - public void Callback(Runtime.PyObject self) - { - using (Runtime.Py.GIL()) - ((dynamic)self).PyCallback(self); - } + } + + //========================================================================== + // Tests calling from Python into C# and back into Python using a PyObject. + // SelfCallbackTest should be inherited by a Python class. + // Used in test_class.py / testCallback + //========================================================================== + public class SelfCallbackTest + { + public void Callback(Runtime.PyObject self) + { + using (Runtime.Py.GIL()) + ((dynamic)self).PyCallback(self); + } } }