Skip to content

Exception thrown when calling a parameterless constructor that has overload with at least one parameter and params #1302

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BadSingleton opened this issue Dec 3, 2020 · 0 comments

Comments

@BadSingleton
Copy link
Contributor

Environment

  • Pythonnet version: master@c81c3c3db7fcc403d5f4e8298b320240829daab2
  • Python version: 3.7, 3.9 (both x64)
  • Operating System: Windows

Details

This is a regression introduced in c81c3c3 .

  • If there is a parameterless constructor (and probably a method too) that has an overload with at least one parameter params parameter, when called from Python, an InvalidIndexError will be raised from Python for .NET.

Callstack from when called from within Unity

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
---
at System.Collections.ArrayList.get_Item (System.Int32 index) [0x0001c] in <437ba245d8404784b9fbab9b439ac908>:0 
  at Python.Runtime.MethodBinder.TryConvertArguments (System.Reflection.ParameterInfo[] pi, System.Boolean paramsArray, System.IntPtr args, System.Int32 pyArgCount, System.Collections.Generic.Dictionary`2[TKey,TValue] kwargDict, System.Collections.ArrayList defaultArgList, System.Boolean needsResolution, System.Int32& outs) [0x0008a] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.MethodBinder.Bind (System.IntPtr inst, System.IntPtr args, System.IntPtr kw, System.Reflection.MethodBase info, System.Reflection.MethodInfo[] methodinfo) [0x0017c] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.MethodBinder.Bind (System.IntPtr inst, System.IntPtr args, System.IntPtr kw, System.Reflection.MethodBase info) [0x00000] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.ConstructorBinder.InvokeRaw (System.IntPtr inst, System.IntPtr args, System.IntPtr kw, System.Reflection.MethodBase info) [0x00074] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.ConstructorBinder.InvokeRaw (System.IntPtr inst, System.IntPtr args, System.IntPtr kw) [0x00000] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.ClassObject.tp_new (System.IntPtr tp, System.IntPtr args, System.IntPtr kw) [0x000b5] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.NativeCall.Call_3 (System.IntPtr fp, System.IntPtr a1, System.IntPtr a2, System.IntPtr a3) [0x00006] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at Python.Runtime.MetaType.tp_call (System.IntPtr tp, System.IntPtr args, System.IntPtr kw) [0x00024] in <d0b807c6e27c43ea84a0e3a3c643e888>:0 
  at (wrapper managed-to-native) Python.Runtime.Runtime.PyRun_String(string,Python.Runtime.RunFlagType,intptr,intptr)

I have a patch to show how to reproduce it (although it crashes pytest)

diff --git a/src/testing/constructortests.cs b/src/testing/constructortests.cs
index 8800c94..ecc61ce 100644
--- a/src/testing/constructortests.cs
+++ b/src/testing/constructortests.cs
@@ -48,4 +48,22 @@ namespace Python.Test
             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 5e54896..c305377 100644
--- a/src/tests/test_constructors.py
+++ b/src/tests/test_constructors.py
@@ -44,3 +44,12 @@ def test_subclass_constructor():
     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 == ""

filmor added a commit to filmor/pythonnet that referenced this issue Dec 3, 2020
We can match n Python parameters to exactly n+1 C# parameters of which
the last one is a param-array.

Fixes pythonnet#1302.
BadSingleton added a commit to Unity-Technologies/pythonnet that referenced this issue Dec 4, 2020
BadSingleton added a commit to Unity-Technologies/pythonnet that referenced this issue Dec 9, 2020
filmor added a commit to filmor/pythonnet that referenced this issue Dec 10, 2020
We can match n Python parameters to exactly n+1 C# parameters of which
the last one is a param-array.

Fixes pythonnet#1302.
@filmor filmor closed this as completed in 4133927 Dec 10, 2020
BadSingleton added a commit to Unity-Technologies/pythonnet that referenced this issue Dec 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant