From 001aeec433744d98ed4d1a02e0b6667ef425c414 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 3 Dec 2020 22:08:32 +0100 Subject: [PATCH 1/3] Ensure that param-array matching works correctly We can match n Python parameters to exactly n+1 C# parameters of which the last one is a param-array. Fixes #1302. --- src/runtime/methodbinder.cs | 6 +++--- src/testing/constructortests.cs | 18 ++++++++++++++++++ src/tests/test_constructors.py | 9 +++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/runtime/methodbinder.cs b/src/runtime/methodbinder.cs index 69b7908e9..2cf548f48 100644 --- a/src/runtime/methodbinder.cs +++ b/src/runtime/methodbinder.cs @@ -512,7 +512,7 @@ static object[] TryConvertArguments(ParameterInfo[] pi, bool paramsArray, { if(arrayStart == paramIndex) { - op = HandleParamsArray(args, arrayStart, pyArgCount, out isNewReference); + op = HandleParamsArray(args, arrayStart, pyArgCount, out isNewReference); } else { @@ -652,7 +652,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa { match = true; } - else if (positionalArgumentCount < parameters.Length) + else if (positionalArgumentCount < parameters.Length && (!paramsArray || positionalArgumentCount == parameters.Length - 1)) { // every parameter past 'positionalArgumentCount' must have either // a corresponding keyword argument or a default parameter @@ -677,7 +677,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa defaultArgList.Add(parameters[v].GetDefaultValue()); defaultsNeeded++; } - else if(!paramsArray) + else if (!paramsArray) { match = false; } diff --git a/src/testing/constructortests.cs b/src/testing/constructortests.cs index 8800c94a1..4dc7f04d8 100644 --- a/src/testing/constructortests.cs +++ b/src/testing/constructortests.cs @@ -48,4 +48,22 @@ public SubclassConstructorTest(Exception v) value = v; } } + + public class MultipleConstructorsTest + { + public string value; + public Type[] type; + + public MultipleConstructorsTest() + { + value = ""; + type = new Type[1] { null }; + } + + public MultipleConstructorsTest(string s, params Type[] tp) + { + value = s; + type = tp; + } + } } diff --git a/src/tests/test_constructors.py b/src/tests/test_constructors.py index 5e5489630..c305377f3 100644 --- a/src/tests/test_constructors.py +++ b/src/tests/test_constructors.py @@ -44,3 +44,12 @@ class Sub(System.Exception): instance = Sub() ob = SubclassConstructorTest(instance) assert isinstance(ob.value, System.Exception) + + +def test_multiple_constructor(): + from Python.Test import MultipleConstructorsTest + import System + + # Test parameterless + ob = MultipleConstructorsTest() + assert ob.value == "" From b9538b9566a3e86b706df3999ab2d4112a75e2ba Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Fri, 4 Dec 2020 07:18:03 +0100 Subject: [PATCH 2/3] Add tests for method matching in presence of param arrays --- src/testing/methodtest.cs | 10 ++++++++++ src/tests/test_method.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/testing/methodtest.cs b/src/testing/methodtest.cs index 62d154539..cd4a740d5 100644 --- a/src/testing/methodtest.cs +++ b/src/testing/methodtest.cs @@ -703,6 +703,16 @@ public static string DefaultParamsWithOverloading(int a = 5, int b = 6, int c = { return $"{a}{b}{c}{d}XXX"; } + + public static string ParamsArrayOverloaded(int i = 1) + { + return "without params-array"; + } + + public static string ParamsArrayOverloaded(int i, params int[] paramsArray) + { + return "with params-array"; + } } diff --git a/src/tests/test_method.py b/src/tests/test_method.py index 8cec02ddc..da43de946 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -1188,3 +1188,37 @@ def test_keyword_arg_method_resolution(): ob = MethodArityTest() assert ob.Foo(1, b=2) == "Arity 2" +def test_params_array_overload(): + res = MethodTest.ParamsArrayOverloaded() + assert res == "without params-array" + + res = MethodTest.ParamsArrayOverloaded(1) + assert res == "without params-array" + + res = MethodTest.ParamsArrayOverloaded(i=1) + assert res == "without params-array" + + res = MethodTest.ParamsArrayOverloaded(1, 2) + assert res == "with params-array" + + res = MethodTest.ParamsArrayOverloaded(1, 2, 3) + assert res == "with params-array" + + res = MethodTest.ParamsArrayOverloaded(1, 2, 3, i=1) + assert res == "with params-array" + + # res = MethodTest.ParamsArrayOverloaded(paramsArray=[], i=1) + # assert res == "with params-array" + + res = MethodTest.ParamsArrayOverloaded(1, paramsArray=[]) + assert res == "with params-array" + + res = MethodTest.ParamsArrayOverloaded(1, i=1) + assert res == "with params-array" + + # res = MethodTest.ParamsArrayOverloaded(1, 2, i=1) + # assert res == "with params-array" + + # res = MethodTest.ParamsArrayOverloaded(1, 2, 3, i=1) + # assert res == "with params-array" + From f86676465f2a651daa06000863c4b43bf7bd54ad Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 10 Dec 2020 18:42:55 +0100 Subject: [PATCH 3/3] Add comment to the commented out tests --- src/tests/test_method.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/tests/test_method.py b/src/tests/test_method.py index da43de946..344734642 100644 --- a/src/tests/test_method.py +++ b/src/tests/test_method.py @@ -1204,21 +1204,20 @@ def test_params_array_overload(): res = MethodTest.ParamsArrayOverloaded(1, 2, 3) assert res == "with params-array" - res = MethodTest.ParamsArrayOverloaded(1, 2, 3, i=1) - assert res == "with params-array" - - # res = MethodTest.ParamsArrayOverloaded(paramsArray=[], i=1) - # assert res == "with params-array" - res = MethodTest.ParamsArrayOverloaded(1, paramsArray=[]) assert res == "with params-array" res = MethodTest.ParamsArrayOverloaded(1, i=1) assert res == "with params-array" + res = MethodTest.ParamsArrayOverloaded(1, 2, 3, i=1) + assert res == "with params-array" + + # These two cases are still incorrectly failing: + # res = MethodTest.ParamsArrayOverloaded(1, 2, i=1) # assert res == "with params-array" - # res = MethodTest.ParamsArrayOverloaded(1, 2, 3, i=1) + # res = MethodTest.ParamsArrayOverloaded(paramsArray=[], i=1) # assert res == "with params-array"