From 2a2c9c71ec0c6e54d95ca0a950dccbf07d323d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigbj=C3=B8rn=20Helset?= Date: Thu, 30 Jun 2016 16:26:55 +0200 Subject: [PATCH 01/13] added intial test that illustrates how int->double conversion works in calling a constructor, prior to the change in the methodbinder.cs, this test failed, since the no-match in ct. was failing silently, now it works. Next step is to give exception when ct args do not match --- pythonnet.sln | 12 +++++++-- src/clrmodule/clrmodule.csproj | 1 + src/console/Console.csproj | 3 ++- src/embed_tests/Python.EmbeddingTest.csproj | 1 + src/runtime/Python.Runtime.csproj | 1 + src/runtime/methodbinder.cs | 28 +++++++++++++++++++-- src/testing/Python.Test.csproj | 1 + src/testing/constructortests.cs | 23 ++++++++++++++++- src/tests/test_constructors.py | 13 ++++++++++ 9 files changed, 77 insertions(+), 6 deletions(-) diff --git a/pythonnet.sln b/pythonnet.sln index 64bf45fa2..64f8d4a95 100644 --- a/pythonnet.sln +++ b/pythonnet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{097B4AC0-74E9-4C58-BCF8-C69746EC8271}" EndProject @@ -89,10 +89,18 @@ Global {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x64.Build.0 = Release|x64 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.ActiveCfg = Release|x86 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.Build.0 = Release|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.ActiveCfg = DebugMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.Build.0 = DebugMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.ActiveCfg = DebugMono|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.Build.0 = DebugMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.ActiveCfg = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.Build.0 = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.ActiveCfg = DebugWin|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.Build.0 = DebugWin|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.Build.0 = ReleaseMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.Build.0 = ReleaseMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.Build.0 = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86 diff --git a/src/clrmodule/clrmodule.csproj b/src/clrmodule/clrmodule.csproj index a062d3bf2..af0a191a2 100644 --- a/src/clrmodule/clrmodule.csproj +++ b/src/clrmodule/clrmodule.csproj @@ -107,6 +107,7 @@ true true false + PYTHON34;UCS2 diff --git a/src/console/Console.csproj b/src/console/Console.csproj index 77406e6c5..0c4297cae 100644 --- a/src/console/Console.csproj +++ b/src/console/Console.csproj @@ -144,6 +144,7 @@ true false 4 + TRACE;PYTHON34, UCS2 True @@ -196,7 +197,7 @@ - Python.Runtime.dll + Python.Runtime.dll diff --git a/src/embed_tests/Python.EmbeddingTest.csproj b/src/embed_tests/Python.EmbeddingTest.csproj index 80a4a9820..030db8570 100644 --- a/src/embed_tests/Python.EmbeddingTest.csproj +++ b/src/embed_tests/Python.EmbeddingTest.csproj @@ -126,6 +126,7 @@ true true false + PYTHON34, UCS2 diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index 1e54d2742..98156c8eb 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -51,6 +51,7 @@ x64 false true + PYTHON34, UCS2 true diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index 22aaf33e4..fa63982a6 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -375,8 +375,20 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, Runtime.Decref(pyoptype); if (!typematch) { - margs = null; - break; + if (SimplePromotableType(clrtype, pi[n].ParameterType)) + { + if (!Converter.ToManaged(op, pi[n].ParameterType, out arg, false)) + { + margs = null;// basically we are failing this match, but can't throw yet + break; + } + } + else + { + margs = null; + break; + } + } } else @@ -455,6 +467,18 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, } return null; } + /// + /// Returns true if src type (int -type) is promotable to a higher resolution type (float|double) + /// + /// + /// + /// + private bool SimplePromotableType(Type src, Type dst) + { + return (((src == typeof(int) || src == typeof(short)) && (dst == typeof(double) || dst == typeof(float)))) + || ((src == typeof(long)) && (dst == typeof(double))) + || ((src ==typeof(int) || src == typeof(short)) && (dst == typeof(long))); + } internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw) { diff --git a/src/testing/Python.Test.csproj b/src/testing/Python.Test.csproj index 354a6eae6..df494ddb8 100644 --- a/src/testing/Python.Test.csproj +++ b/src/testing/Python.Test.csproj @@ -105,6 +105,7 @@ true true false + PYTHON34, UCS2 diff --git a/src/testing/constructortests.cs b/src/testing/constructortests.cs index cffcee888..47d315290 100644 --- a/src/testing/constructortests.cs +++ b/src/testing/constructortests.cs @@ -7,7 +7,28 @@ namespace Python.Test //======================================================================== // These classes support the CLR constructor unit tests. //======================================================================== - + public class AConstrucorTest + { + public string name; + public AConstrucorTest(string n) { name = n; } + } + public class LinkConstructorTest + { + public LinkConstructorTest() + { + DefaultCtCalled = true; + } + public LinkConstructorTest(AConstrucorTest a,double matchMe,AConstrucorTest b) + { + MatchMe = matchMe; + a1 = a; + a2 = b; + } + public bool DefaultCtCalled; + public double MatchMe; + public AConstrucorTest a1; + public AConstrucorTest a2; + } public class EnumConstructorTest { public TypeCode value; diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index fdc1ef060..4e7b86552 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -47,6 +47,19 @@ class sub(System.Exception): print(ob) self.assertTrue(isinstance(ob.value, System.Exception)) + def testConstructorArgumentMatching(self): + """ Test that simple type promitions works for int->double """ + from Python.Test import AConstrucorTest, LinkConstructorTest + a1=AConstrucorTest('a1') + a2=AConstrucorTest('a2') + self.assertEqual(a1.name,'a1') + self.assertEqual(a2.name, 'a2') + l1=LinkConstructorTest(a1,3000,a2) + #l2=LinkConstructorTest(a1,3000.0,a2) + self.assertEqual(l1.a1.name, a1.name) + self.assertEqual(l1.a2.name, a2.name) + self.assertAlmostEqual(3000.0,l1.MatchMe) + def test_suite(): return unittest.makeSuite(ConstructorTests) From 78dca296e7afc27c491544818dcf2610eebc64d9 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sun, 3 Jul 2016 14:20:45 +0200 Subject: [PATCH 02/13] ease windows development, - default settings after checkout reflecting most recent python, so that build and test works without fiddling with settings in vs 2015 --- pythonnet.sln | 12 ++++++++++-- src/clrmodule/clrmodule.csproj | 1 + src/runtime/Python.Runtime.csproj | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pythonnet.sln b/pythonnet.sln index 64bf45fa2..e21ef5551 100644 --- a/pythonnet.sln +++ b/pythonnet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{097B4AC0-74E9-4C58-BCF8-C69746EC8271}" EndProject @@ -89,10 +89,18 @@ Global {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x64.Build.0 = Release|x64 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.ActiveCfg = Release|x86 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.Build.0 = Release|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.ActiveCfg = DebugMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.Build.0 = DebugMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.ActiveCfg = DebugMono|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.Build.0 = DebugMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.ActiveCfg = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.Build.0 = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.ActiveCfg = DebugWin|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.Build.0 = DebugWin|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.Build.0 = ReleaseMono|x64 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86 + {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.Build.0 = ReleaseMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.Build.0 = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86 diff --git a/src/clrmodule/clrmodule.csproj b/src/clrmodule/clrmodule.csproj index a062d3bf2..a0ea267e8 100644 --- a/src/clrmodule/clrmodule.csproj +++ b/src/clrmodule/clrmodule.csproj @@ -107,6 +107,7 @@ true true false + PYTHON35,UCS2 diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index 1e54d2742..81dce42d1 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -51,6 +51,7 @@ x64 false true + PYTHON35,UCS2 true @@ -93,6 +94,7 @@ false full x64 + TRACE;DEBUG;PYTHON35,UCS2 From af1b937c6b342bfad304351329265dcf8959237b Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sun, 3 Jul 2016 14:49:57 +0200 Subject: [PATCH 03/13] added method tests for simple promotions int->float, int->double --- src/testing/methodtest.cs | 18 ++++++++++++++++++ src/tests/test_method.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/testing/methodtest.cs b/src/testing/methodtest.cs index 675b1577c..fcdbbd1cc 100644 --- a/src/testing/methodtest.cs +++ b/src/testing/methodtest.cs @@ -73,6 +73,24 @@ public Guid TestStructConversion(Guid v) { return v; } + /// + /// Method to support testing + /// simple promotion of numeric types: + /// + /// integer types -> double + /// + /// + /// + /// + /// + public double TestSimpleIntToDoubleTypePromotion(double a, double b) + { + return a + b; + } + public float TestSimpleIntToFloatTypePromotion(float a, float b) + { + return a + b; + } public Exception TestSubclassConversion(Exception v) { diff --git a/src/tests/test_method.py b/src/tests/test_method.py index 4728d13e4..4dd47e6da 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -208,6 +208,45 @@ def testMethodCallFlagsConversion(self): r = object.TestFlagsConversion(flags) self.assertTrue(r == flags) + def testSimpleTypePromotionIntToDouble(self): + object = MethodTest() + try: + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) + except: + self.assertTrue(False,"Type promotion from int to double failed") + + try: + should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'2.0') + self.assertTrue(False,"the promotion of string to double should fail") + except: + pass + + def testSimpleTypePromotionIntToFloat(self): + object = MethodTest() + try: + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) + except: + self.assertTrue(False,"Type promotion from int to float failed") + try: + should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'2.0') + self.assertTrue(False,"the promotion of string to float should fail") + except: + pass + def testMethodCallStructConversion(self): """Test struct conversion in method call.""" from System import Guid From 24baadffeef457fb9b8c9f2cebc42aaae3ca95ba Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sun, 3 Jul 2016 15:14:48 +0200 Subject: [PATCH 04/13] extending test to cover negative outcome of bool->double|float --- src/tests/test_method.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/tests/test_method.py b/src/tests/test_method.py index 4dd47e6da..defb3271c 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -227,6 +227,11 @@ def testSimpleTypePromotionIntToDouble(self): self.assertTrue(False,"the promotion of string to double should fail") except: pass + try: + should_fail = object.TestSimpleIntToDoubleTypePromotion(2,True) + self.assertTrue(False,"the promotion of boolean to double should fail") + except: + pass def testSimpleTypePromotionIntToFloat(self): object = MethodTest() @@ -242,10 +247,15 @@ def testSimpleTypePromotionIntToFloat(self): except: self.assertTrue(False,"Type promotion from int to float failed") try: - should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'2.0') + should_fail = object.TestSimpleIntToFloatTypePromotion(2,'2.0') self.assertTrue(False,"the promotion of string to float should fail") except: pass + try: + should_fail = object.TestSimpleIntToFloatTypePromotion(2,True) + self.assertTrue(False,"the promotion of boolean to float should fail") + except: + pass def testMethodCallStructConversion(self): """Test struct conversion in method call.""" From bde42585a297cf57a8aca30d42f63cccfdd83df3 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sun, 3 Jul 2016 15:32:32 +0200 Subject: [PATCH 05/13] adding default ct to challenge the matching mechanism --- src/testing/constructortests.cs | 32 ++++++++++++++++++++++++++++++++ src/tests/test_constructors.py | 11 ++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/testing/constructortests.cs b/src/testing/constructortests.cs index cffcee888..f79dbff89 100644 --- a/src/testing/constructortests.cs +++ b/src/testing/constructortests.cs @@ -50,4 +50,36 @@ public SubclassConstructorTest(Exception v) this.value = v; } } + public class ToDoubleConstructorTest + { + public ToDoubleConstructorTest() + { + //Just default values + } + public ToDoubleConstructorTest(string a, double b,string c) + { + this.a = a; + this.b = b; + this.c = c; + } + public string a; + public double b; + public string c; + } + public class ToFloatConstructorTest + { + public ToFloatConstructorTest() + { + // just default values. + } + public ToFloatConstructorTest(string a, float b, string c) + { + this.a = a; + this.b = b; + this.c = c; + } + public string a; + public float b; + public string c; + } } \ No newline at end of file diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index fdc1ef060..1f7341eea 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -44,9 +44,18 @@ class sub(System.Exception): instance = sub() ob = SubclassConstructorTest(instance) - print(ob) self.assertTrue(isinstance(ob.value, System.Exception)) + def testIntToDoubleConstructorArguments(self): + from Python.Test import ToDoubleConstructorTest + + o = ToDoubleConstructorTest('a',2,'c') + self.assertEqual(o.a,'a') + self.assertAlmostEqual(o.b,2) + self.assertEqual(o.c,'c') + + o = ToDoubleConstructorTest() + def test_suite(): return unittest.makeSuite(ConstructorTests) From a65d7930936f9b8d9511e542974e371817d71261 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sun, 3 Jul 2016 20:40:55 +0200 Subject: [PATCH 06/13] adding test, and print-out warning for the not yet implemented feature --- src/tests/test_constructors.py | 14 ++++++- src/tests/test_method.py | 72 ++++++++++++++-------------------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index 51b2abc14..9b14a5ed0 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -68,7 +68,7 @@ def testIntToDoubleConstructorArguments(self): self.assertAlmostEqual(o.b,2) self.assertEqual(o.c,'c') - o = ToDoubleConstructorTest() + o = ToDoubleConstructorTest() # just to verify the default constructor is there def testIntToFloatConstructorArguments(self): from Python.Test import ToFloatConstructorTest @@ -80,6 +80,18 @@ def testIntToFloatConstructorArguments(self): o = ToFloatConstructorTest() + def testConstructorRaiseExceptionIfNoMatch(self): + from Python.Test import ToDoubleConstructorTest + constructor_throw_on_arg_match_is_fixed=False + + if constructor_throw_on_arg_match_is_fixed: + with self.assertRaises(TypeError): + o = ToDoubleConstructorTest('a','not a number','c') # this should raise exception, because there are no match! + else: + print("\n\n*** Warning: failing arg match on constructors are currently silently accepted if there is a null constructor\n") + + + def test_suite(): return unittest.makeSuite(ConstructorTests) diff --git a/src/tests/test_method.py b/src/tests/test_method.py index defb3271c..d7a178190 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -210,52 +210,38 @@ def testMethodCallFlagsConversion(self): def testSimpleTypePromotionIntToDouble(self): object = MethodTest() - try: - sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2.0) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2.0) - self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) - except: - self.assertTrue(False,"Type promotion from int to double failed") - - try: - should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'2.0') - self.assertTrue(False,"the promotion of string to double should fail") - except: - pass - try: - should_fail = object.TestSimpleIntToDoubleTypePromotion(2,True) - self.assertTrue(False,"the promotion of boolean to double should fail") - except: - pass + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) + + with self.assertRaises(TypeError): + should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'x2.0') + #with self.assertRaises(TypeError): + # should_fail = object.TestSimpleIntToDoubleTypePromotion(2,True) def testSimpleTypePromotionIntToFloat(self): object = MethodTest() - try: - sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2.0) - self.assertAlmostEqual(sum_of_a_plus_b,2+2) - sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2.0) - self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) - except: - self.assertTrue(False,"Type promotion from int to float failed") - try: - should_fail = object.TestSimpleIntToFloatTypePromotion(2,'2.0') - self.assertTrue(False,"the promotion of string to float should fail") - except: - pass - try: - should_fail = object.TestSimpleIntToFloatTypePromotion(2,True) - self.assertTrue(False,"the promotion of boolean to float should fail") - except: - pass + + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2+2) + sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2.0) + self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) + + with self.assertRaises(TypeError): + should_fail = object.TestSimpleIntToFloatTypePromotion(2,'x2.0') + # bool True-> 1.0, False -> 0.0 + #with self.assertRaises(TypeError): + # should_fail = object.TestSimpleIntToFloatTypePromotion(2,True) + # print("And the unexpected result is...",should_fail) def testMethodCallStructConversion(self): """Test struct conversion in method call.""" From e698b57af58115568107f6a5275e2d3302b2b465 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 00:12:06 +0200 Subject: [PATCH 07/13] added more test for illustrating super/sub-class and argument passing problems, tests runs, but with warning printed out --- src/tests/test_constructors.py | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index 9b14a5ed0..ca09807c5 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -5,6 +5,8 @@ import Python.Test as Test import System +constructor_throw_on_arg_match_is_fixed = False # currently, failed match on super() is silently ignored, and tests will fail if set to true +constructor_to_sub_class_accepts_specific_parameters= False # currently, we can't pass arguments to super() class ct. class ConstructorTests(unittest.TestCase): """Test CLR class constructor support.""" @@ -46,6 +48,27 @@ class sub(System.Exception): ob = SubclassConstructorTest(instance) self.assertTrue(isinstance(ob.value, System.Exception)) + def testSubClassWithInternalArgsPassedToSuper(self): + """ + Verify we can sub-class a .NET class, in python, + and pass a working set of arguments to our super class. + """ + from Python.Test import ToDoubleConstructorTest # does the job for this test + + class PySubClass(ToDoubleConstructorTest): + def __init__(self,d): + super().__init__('a',2.0,'c') + self.d = d + + o = PySubClass('d') + self.assertEqual( o.d,'d') + if constructor_to_sub_class_accepts_specific_parameters: + self.assertEqual( o.a,'a') + self.assertAlmostEqual(o.b,2.0) + self.assertEqual( o.c,'c') + else: + print("\n\n*** Warning passing parameters to super class is currently not verified\n") + def testConstructorArgumentMatching(self): """ Test that simple type promitions works for int->double """ @@ -81,8 +104,21 @@ def testIntToFloatConstructorArguments(self): o = ToFloatConstructorTest() def testConstructorRaiseExceptionIfNoMatch(self): + """ + Notice: Due to the feature of .NET object as super-class, there is a + 'hack' that after calling a constructor with the supplied arguments + (and they fail to match the .NET class constructor for any reason) + then it removes all the arguments, and retry the call. + Now, if this succeeds, it will return an object, with default values. + This *could* make sense, given that the .NET class *IS* subclassed, + however, if the process is *not* a part of a sub-class construction, + then this is at best very unexpected. + + + """ + from Python.Test import ToDoubleConstructorTest - constructor_throw_on_arg_match_is_fixed=False + if constructor_throw_on_arg_match_is_fixed: with self.assertRaises(TypeError): From 1fd75b3b194c55b97ea757b7392e72be22a2895a Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 17:31:45 +0200 Subject: [PATCH 08/13] fixed py 2.7 syntax for super, plus fixed typo --- src/testing/constructortests.cs | 10 +++++----- src/tests/test_constructors.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/testing/constructortests.cs b/src/testing/constructortests.cs index b05184d8a..b7d39d1f6 100644 --- a/src/testing/constructortests.cs +++ b/src/testing/constructortests.cs @@ -7,10 +7,10 @@ namespace Python.Test //======================================================================== // These classes support the CLR constructor unit tests. //======================================================================== - public class AConstrucorTest + public class AConstructorTest { public string name; - public AConstrucorTest(string n) { name = n; } + public AConstructorTest(string n) { name = n; } } public class LinkConstructorTest { @@ -18,7 +18,7 @@ public LinkConstructorTest() { DefaultCtCalled = true; } - public LinkConstructorTest(AConstrucorTest a,double matchMe,AConstrucorTest b) + public LinkConstructorTest(AConstructorTest a,double matchMe,AConstructorTest b) { MatchMe = matchMe; a1 = a; @@ -26,8 +26,8 @@ public LinkConstructorTest(AConstrucorTest a,double matchMe,AConstrucorTest b) } public bool DefaultCtCalled; public double MatchMe; - public AConstrucorTest a1; - public AConstrucorTest a2; + public AConstructorTest a1; + public AConstructorTest a2; } public class EnumConstructorTest { diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index ca09807c5..92db741ef 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -57,7 +57,7 @@ def testSubClassWithInternalArgsPassedToSuper(self): class PySubClass(ToDoubleConstructorTest): def __init__(self,d): - super().__init__('a',2.0,'c') + super(PySubClass, self).__init__('a',2.0,'c') self.d = d o = PySubClass('d') @@ -72,9 +72,9 @@ def __init__(self,d): def testConstructorArgumentMatching(self): """ Test that simple type promitions works for int->double """ - from Python.Test import AConstrucorTest, LinkConstructorTest - a1=AConstrucorTest('a1') - a2=AConstrucorTest('a2') + from Python.Test import AConstructorTest, LinkConstructorTest + a1=AConstructorTest('a1') + a2=AConstructorTest('a2') self.assertEqual(a1.name,'a1') self.assertEqual(a2.name, 'a2') l1=LinkConstructorTest(a1,3000,a2) From fb9b21e5cf5c8ab2fe4d08e178c9d571b9f1ba7c Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 19:34:13 +0200 Subject: [PATCH 09/13] reverted the .sln to unmodified state --- pythonnet.sln | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/pythonnet.sln b/pythonnet.sln index e21ef5551..64bf45fa2 100644 --- a/pythonnet.sln +++ b/pythonnet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30110.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{097B4AC0-74E9-4C58-BCF8-C69746EC8271}" EndProject @@ -89,18 +89,10 @@ Global {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x64.Build.0 = Release|x64 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.ActiveCfg = Release|x86 {E29DCF0A-5114-4A98-B1DD-71264B6EA349}.ReleaseWin|x86.Build.0 = Release|x86 - {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.ActiveCfg = DebugMono|x64 - {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x64.Build.0 = DebugMono|x64 - {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.ActiveCfg = DebugMono|x86 - {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugMono|x86.Build.0 = DebugMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.ActiveCfg = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x64.Build.0 = DebugWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.ActiveCfg = DebugWin|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.DebugWin|x86.Build.0 = DebugWin|x86 - {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64 - {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x64.Build.0 = ReleaseMono|x64 - {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86 - {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseMono|x86.Build.0 = ReleaseMono|x86 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x64.Build.0 = ReleaseWin|x64 {86E834DE-1139-4511-96CC-69636A56E7AC}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86 From 9e1d72b213de710f525dcad3d59d6167fc2f6884 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 19:43:34 +0200 Subject: [PATCH 10/13] reverting changes to runtime and clrmodule projects --- src/clrmodule/clrmodule.csproj | 1 - src/runtime/Python.Runtime.csproj | 20 +++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/clrmodule/clrmodule.csproj b/src/clrmodule/clrmodule.csproj index a0ea267e8..a062d3bf2 100644 --- a/src/clrmodule/clrmodule.csproj +++ b/src/clrmodule/clrmodule.csproj @@ -107,7 +107,6 @@ true true false - PYTHON35,UCS2 diff --git a/src/runtime/Python.Runtime.csproj b/src/runtime/Python.Runtime.csproj index f68d01c2d..1e54d2742 100644 --- a/src/runtime/Python.Runtime.csproj +++ b/src/runtime/Python.Runtime.csproj @@ -13,18 +13,18 @@ bin\x86\ReleaseMono\ - PYTHON35, UCS4 + PYTHON27, UCS4 true true pdbonly x86 false true - PYTHON35,UCS2 + PYTHON27,UCS2 bin\x64\ReleaseMono\ - PYTHON35, UCS4 + PYTHON27, UCS4 true true pdbonly @@ -34,7 +34,7 @@ bin\x86\ReleaseWin\ - PYTHON35, UCS2 + PYTHON27, UCS2 true true pdbonly @@ -44,19 +44,18 @@ bin\x64\ReleaseWin\ - PYTHON35, UCS2 + PYTHON27, UCS2 true true pdbonly x64 false true - PYTHON35,UCS2 true bin\x86\DebugMono\ - TRACE;DEBUG;PYTHON35,UCS4 + TRACE;DEBUG;PYTHON27,UCS4 true false full @@ -68,7 +67,7 @@ true bin\x64\DebugMono\ - TRACE;DEBUG;PYTHON35,UCS4 + TRACE;DEBUG;PYTHON27,UCS4 true false full @@ -77,7 +76,7 @@ true bin\x86\DebugWin\ - TRACE;DEBUG;PYTHON35,UCS2 + TRACE;DEBUG;PYTHON27,UCS2 true false full @@ -89,12 +88,11 @@ true bin\x64\DebugWin\ - TRACE;DEBUG;PYTHON35,UCS2 + TRACE;DEBUG;PYTHON27,UCS2 true false full x64 - TRACE;DEBUG;PYTHON35,UCS2 From 0e2cd12ccdd0dd0de7abfd2cfff990164965db5f Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 19:47:42 +0200 Subject: [PATCH 11/13] Reverting changes to Console, embed_tests and testing .csproj files --- src/console/Console.csproj | 3 +-- src/embed_tests/Python.EmbeddingTest.csproj | 1 - src/testing/Python.Test.csproj | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/console/Console.csproj b/src/console/Console.csproj index 0c4297cae..77406e6c5 100644 --- a/src/console/Console.csproj +++ b/src/console/Console.csproj @@ -144,7 +144,6 @@ true false 4 - TRACE;PYTHON34, UCS2 True @@ -197,7 +196,7 @@ - Python.Runtime.dll + Python.Runtime.dll diff --git a/src/embed_tests/Python.EmbeddingTest.csproj b/src/embed_tests/Python.EmbeddingTest.csproj index 030db8570..80a4a9820 100644 --- a/src/embed_tests/Python.EmbeddingTest.csproj +++ b/src/embed_tests/Python.EmbeddingTest.csproj @@ -126,7 +126,6 @@ true true false - PYTHON34, UCS2 diff --git a/src/testing/Python.Test.csproj b/src/testing/Python.Test.csproj index df494ddb8..354a6eae6 100644 --- a/src/testing/Python.Test.csproj +++ b/src/testing/Python.Test.csproj @@ -105,7 +105,6 @@ true true false - PYTHON34, UCS2 From e58d5b25cf35b9cc28b00425bfd6b24c39eab0d6 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Mon, 4 Jul 2016 23:39:22 +0200 Subject: [PATCH 12/13] Hopefully fixed py 2.6 issues --- src/tests/test_constructors.py | 5 ++++- src/tests/test_method.py | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index 92db741ef..d7bb80cab 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -121,8 +121,11 @@ def testConstructorRaiseExceptionIfNoMatch(self): if constructor_throw_on_arg_match_is_fixed: - with self.assertRaises(TypeError): + try: o = ToDoubleConstructorTest('a','not a number','c') # this should raise exception, because there are no match! + except TypeError: + return + self.fail("exception should be raised for non-matching constructor atempt") else: print("\n\n*** Warning: failing arg match on constructors are currently silently accepted if there is a null constructor\n") diff --git a/src/tests/test_method.py b/src/tests/test_method.py index d7a178190..a00b024d1 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -219,10 +219,13 @@ def testSimpleTypePromotionIntToDouble(self): sum_of_a_plus_b = object.TestSimpleIntToDoubleTypePromotion(2.0,2.0) self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) - with self.assertRaises(TypeError): + #with self.assertRaises(TypeError), wont work on py 2.6, so .. + try: should_fail = object.TestSimpleIntToDoubleTypePromotion(2,'x2.0') - #with self.assertRaises(TypeError): - # should_fail = object.TestSimpleIntToDoubleTypePromotion(2,True) + except TypeError: + return + self.fail("A string (not convertible to number), should throw type error") + # TODO: consider this for consistence: bool True-> 1.0, False -> 0.0 def testSimpleTypePromotionIntToFloat(self): object = MethodTest() @@ -235,13 +238,12 @@ def testSimpleTypePromotionIntToFloat(self): self.assertAlmostEqual(sum_of_a_plus_b,2+2) sum_of_a_plus_b = object.TestSimpleIntToFloatTypePromotion(2.0,2.0) self.assertAlmostEqual(sum_of_a_plus_b,2.0+2.0) - - with self.assertRaises(TypeError): + try: should_fail = object.TestSimpleIntToFloatTypePromotion(2,'x2.0') - # bool True-> 1.0, False -> 0.0 - #with self.assertRaises(TypeError): - # should_fail = object.TestSimpleIntToFloatTypePromotion(2,True) - # print("And the unexpected result is...",should_fail) + except TypeError: + return + self.fail("A string (not convertible to number), should throw type error") + # TODO: consider this for consistence: bool True-> 1.0, False -> 0.0 def testMethodCallStructConversion(self): """Test struct conversion in method call.""" From bdbaa626a496354d1eaf2f5f2d6739f4dbe627b9 Mon Sep 17 00:00:00 2001 From: sigbjorn Date: Sat, 23 Jul 2016 17:59:59 +0200 Subject: [PATCH 13/13] SimplePromotableType simplified, returns true if src is int-type and destination type is float or double, leaving overflow checking entirely to the conversion routine --- src/runtime/methodbinder.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index fa63982a6..0d1ddccac 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -469,15 +469,16 @@ internal Binding Bind(IntPtr inst, IntPtr args, IntPtr kw, } /// /// Returns true if src type (int -type) is promotable to a higher resolution type (float|double) + /// no sanity check for overflow is done, this is done elsewhere when performing + /// the actual conversion. + /// /// /// /// /// private bool SimplePromotableType(Type src, Type dst) { - return (((src == typeof(int) || src == typeof(short)) && (dst == typeof(double) || dst == typeof(float)))) - || ((src == typeof(long)) && (dst == typeof(double))) - || ((src ==typeof(int) || src == typeof(short)) && (dst == typeof(long))); + return (((src == typeof(int) || src == typeof(short) || src == typeof(long) ) && (dst == typeof(double) || dst == typeof(float)))); } internal virtual IntPtr Invoke(IntPtr inst, IntPtr args, IntPtr kw)