From e847024727cac5173c2a0c54903e4d83a7b263ae Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Wed, 7 Dec 2016 21:34:34 -0200 Subject: [PATCH 1/9] Support for System.Decimal Converts System.Decimal to python float --- src/runtime/converter.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index ef3aa3e18..1f1847998 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -101,7 +101,8 @@ internal static IntPtr GetPythonTypeByAlias(Type op) return Runtime.PyLongType; } else if ((op == doubleType) || - (op == singleType)) + (op == singleType) || + (op == decimalType)) { return Runtime.PyFloatType; } @@ -196,6 +197,9 @@ internal static IntPtr ToPython(Object value, Type type) case TypeCode.Double: return Runtime.PyFloat_FromDouble((double)value); + case TypeCode.Decimal: + return Runtime.PyFloat_FromDouble(Convert.ToDouble((decimal)value)); + case TypeCode.SByte: return Runtime.PyInt_FromInt32((int)((sbyte)value)); @@ -788,7 +792,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, } - type_error: + type_error: if (setError) { @@ -800,7 +804,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, return false; - overflow: + overflow: if (setError) { From a2effda3792c4017d3d91c216d07a3bbe0b579ba Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Fri, 9 Dec 2016 21:43:31 -0200 Subject: [PATCH 2/9] Support for System.Decimal Implements convertion from System.Decimal to decimal.Decimal --- src/runtime/converter.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 1f1847998..3fcc8e80b 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -197,9 +197,6 @@ internal static IntPtr ToPython(Object value, Type type) case TypeCode.Double: return Runtime.PyFloat_FromDouble((double)value); - case TypeCode.Decimal: - return Runtime.PyFloat_FromDouble(Convert.ToDouble((decimal)value)); - case TypeCode.SByte: return Runtime.PyInt_FromInt32((int)((sbyte)value)); @@ -212,6 +209,17 @@ internal static IntPtr ToPython(Object value, Type type) case TypeCode.UInt64: return Runtime.PyLong_FromUnsignedLongLong((ulong)value); + case TypeCode.Decimal: + IntPtr mod = Runtime.PyImport_ImportModule("decimal"); + IntPtr ctor = Runtime.PyObject_GetAttrString(mod, "Decimal"); + + string d2s = ((decimal)value).ToString(nfi); + IntPtr d2p = Runtime.PyString_FromString(d2s); + IntPtr args = Runtime.PyTuple_New(1); + Runtime.PyTuple_SetItem(args, 0, d2p); + + return Runtime.PyObject_CallObject(ctor, args); + default: if (value is IEnumerable) { From 27069db748bc94c7c82296398d973d472328fa6e Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Sat, 10 Dec 2016 19:21:48 -0200 Subject: [PATCH 3/9] Support for System.Decimal Implements conversion from decimal.Decimal to System.Decimal --- src/runtime/converter.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 3fcc8e80b..83dcc6936 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -797,10 +797,22 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, } result = d; return true; + + case TypeCode.Decimal: + op = Runtime.PyObject_Str(value); + decimal m; + string sm = Runtime.GetManagedString(op); + if (!Decimal.TryParse(sm, NumberStyles.Number, nfi, out m)) + { + goto type_error; + } + Runtime.XDecref(op); + result = m; + return true; } - type_error: + type_error: if (setError) { @@ -812,7 +824,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, return false; - overflow: + overflow: if (setError) { From 352b3a30bf3c85fd64e7c3d8e7fa05470b78d1e1 Mon Sep 17 00:00:00 2001 From: Alexandre Catarino Date: Tue, 13 Dec 2016 09:30:00 -0200 Subject: [PATCH 4/9] Remove PYTHON_WITHOUT_ENABLE_SHARED config --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 05ae35906..7815152b8 100644 --- a/setup.py +++ b/setup.py @@ -160,7 +160,7 @@ def build_extension(self, ext): enable_shared = False if not enable_shared: - defines.append("PYTHON_WITHOUT_ENABLE_SHARED") + pass#defines.append("PYTHON_WITHOUT_ENABLE_SHARED") if hasattr(sys, "abiflags"): if "d" in sys.abiflags: From 17584fa9942f2a067cd8d7fb0ec2e055ebaba427 Mon Sep 17 00:00:00 2001 From: rmadsen-ks Date: Fri, 16 Dec 2016 17:32:05 +0100 Subject: [PATCH 5/9] 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 --- src/runtime/converter.cs | 13 +++++++++++++ src/runtime/pyobject.cs | 10 ++++++++++ src/testing/callbacktest.cs | 14 ++++++++++++++ src/tests/test_class.py | 15 +++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 83dcc6936..96803d1e5 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -127,6 +127,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. @@ -277,6 +283,13 @@ 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. ManagedType mt = ManagedType.GetManagedObject(value); 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 81389289d..70c7bbc9e 100644 --- a/src/testing/callbacktest.cs +++ b/src/testing/callbacktest.cs @@ -28,4 +28,18 @@ public string Call_simpleDefaultArg_WithEmptyArgs(string moduleName) } } } + + //========================================================================== + // 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); + } + } } diff --git a/src/tests/test_class.py b/src/tests/test_class.py index afb631622..9e2af14da 100644 --- a/src/tests/test_class.py +++ b/src/tests/test_class.py @@ -250,6 +250,21 @@ def testComparisons(self): c2 = ClassTest() self.assertRaises(TypeError, lambda: c1 < c2) + 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 61f5f9aee97ca451b68ecf0d92d1c3d3d202c4ef Mon Sep 17 00:00:00 2001 From: rmadsen-ks Date: Mon, 19 Dec 2016 10:57:53 +0100 Subject: [PATCH 6/9] Removed refcount (#306) --- src/runtime/pyobject.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index ba44c0c21..781f6313d 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -126,17 +126,7 @@ protected virtual void Dispose(bool disposing) disposed = true; } } - - public long RefCount - { - get - { - if(!disposed) - return Runtime.Refcount(obj); - return -1; - } - } - + public void Dispose() { Dispose(true); From 9db24af03ce77232e6d480a93c4fb748f910369f Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Wed, 7 Dec 2016 21:34:34 -0200 Subject: [PATCH 7/9] Support for System.Decimal Converts System.Decimal to python float --- src/runtime/converter.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 96803d1e5..28842b595 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -203,6 +203,9 @@ internal static IntPtr ToPython(Object value, Type type) case TypeCode.Double: return Runtime.PyFloat_FromDouble((double)value); + case TypeCode.Decimal: + return Runtime.PyFloat_FromDouble(Convert.ToDouble((decimal)value)); + case TypeCode.SByte: return Runtime.PyInt_FromInt32((int)((sbyte)value)); @@ -825,7 +828,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, } - type_error: + type_error: if (setError) { @@ -837,7 +840,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, return false; - overflow: + overflow: if (setError) { From 5526607ef51653b060a465a36b089cc8b656a90e Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Fri, 9 Dec 2016 21:43:31 -0200 Subject: [PATCH 8/9] Support for System.Decimal Implements convertion from System.Decimal to decimal.Decimal --- src/runtime/converter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 28842b595..2f56d1f2a 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -203,9 +203,6 @@ internal static IntPtr ToPython(Object value, Type type) case TypeCode.Double: return Runtime.PyFloat_FromDouble((double)value); - case TypeCode.Decimal: - return Runtime.PyFloat_FromDouble(Convert.ToDouble((decimal)value)); - case TypeCode.SByte: return Runtime.PyInt_FromInt32((int)((sbyte)value)); From d26f48af2d9719e6b4a40f881ed623d1148251f6 Mon Sep 17 00:00:00 2001 From: AlexCatarino Date: Sat, 10 Dec 2016 19:21:48 -0200 Subject: [PATCH 9/9] Support for System.Decimal Implements conversion from decimal.Decimal to System.Decimal --- src/runtime/converter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/converter.cs b/src/runtime/converter.cs index 2f56d1f2a..96803d1e5 100644 --- a/src/runtime/converter.cs +++ b/src/runtime/converter.cs @@ -825,7 +825,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, } - type_error: + type_error: if (setError) { @@ -837,7 +837,7 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, return false; - overflow: + overflow: if (setError) {