.Net methods with params Object [] parameters fails when passing System.Object[] in PythonNet 2.5.1, was working in PythonNet 2.4.0
Environment
- Pythonnet version: 2.5.1
- Python version: 3.8.2
- Operating System: Windows10
Details
In PythonNet 2.4.0, invoking .Net functions with params object[] parameter was working on passing System.Object[], but in PythonNet 2.5.1 it is failing. If i pass a Python list it works
Got the following error: Unable to cast object of type 'System.Object[]' to type 'System.IConvertible'.Couldn't store <System.Object[]> in Id Column. Expected type is Int32. at System.Data.DataColumn.set_Item(Int32 record, Object value) at System.Data.DataTable.NewRecordFromArray(Object[] value) at System.Data.DataRowCollection.Add(Object[] values)
import clr
clr.AddReference("System")
clr.AddReference("System.Data")
import System
import System.Data
import System.Collections
dt = System.Data.DataTable()
col = System.Data.DataColumn()
col.ColumnName = "Id"
col.DataType = System.Type.GetType("System.Int32")
dt.Columns.Add(col)
#Working as expected while invoking System.Data.DataRow Add (params object[] values)
dr = dt.Rows.Add(20)
print("Success, Total Rows: %s" %dt.Rows.Count)
#Failing while invoking System.Data.DataRow Add (params object[] values) with System.Object[]
params = System.Collections.ArrayList()
params.Add(10)
paramsArray = params.ToArray()
print(type(paramsArray))
print(paramsArray.GetType())
try:
dt.Rows.Add(paramsArray)
except Exception as e:
print(e)
print("Failure, could not add data row")
#Working as expected if it is passed as python list
paramsArray = [System.Int32(10)]
dt.Rows.Add(paramsArray)
print("Success, Total Rows: %s" %dt.Rows.Count)
This still happens on current master. I'll try to add a test for this.
The issue here is that the code in HandleParamsArray: https://github.com/pythonnet/pythonnet/blob/4133927e5e8a22266a6b9ade8af25986f7f1ec8d/src/runtime/methodbinder.cs#L447
doesn't take into account that the object could be a .NET array. It may need to add a check for .NET arrays, something similar to this, though I don't know if this is performant:
if (!Runtime.PyString_Check(item) && (Runtime.PySequence_Check(item) || (ManagedType.IsManagedType(item) && ManagedType.GetManagedObjectType(item) is ArrayObject)))