pythonnet icon indicating copy to clipboard operation
pythonnet copied to clipboard

.Net methods with params Object [] parameters fails when passing System.Object[] in PythonNet 2.5.1, was working in PythonNet 2.4.0

Open partha-srivi opened this issue 5 years ago • 2 comments

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)

partha-srivi avatar Aug 29 '20 21:08 partha-srivi

This still happens on current master. I'll try to add a test for this.

filmor avatar Dec 10 '20 19:12 filmor

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)))

slide avatar Dec 10 '20 23:12 slide