I want to call a .NET method from python and pass a python object as the parameter. If the .NET function declare the argument type as PyObject, everything is fine, however, if declare the argument type as object or dynamic, exception raised.
In my project, the exception is “System.OverflowException” in GetManagedObject method in managedtype.cs.
In order to reproduce it, I built a minimal example, but a new exception raised "TypeError : No method matches given arguments".
These two exception may have some relationship, so I put this one here first since it has a way to be reproduced.
public object callback(dynamic _para) //TypeError : No method matches given arguments
public object callback(object _para) //TypeError : No method matches given arguments
public object callback(PyObject _para) //passed
This is similar to this issue and this PR fixed it. I tested it, when passing an int or string object the function of 2nd and 3rd signature can be found, but when passing a python object, exception raised.
Here is the minimal example,
using System;
using Python.Runtime;
namespace pythonnetTest
{
public class CallbackBug
{
public void Main()
{
PythonEngine.Initialize();
using (Py.GIL())
{
dynamic sys = PythonEngine.ImportModule("sys");
sys.attr1 = new Callback();
PythonEngine.Exec(
"import sys\n" +
"class template(object):\n" +
" def __init__(self):\n" +
" self.value = None\n" +
" def write(self, msg):\n" +
" self.value = msg\n" +
"para = template()\n" +
//call .NET method and pass a custom python object as the parameter
"sys.attr2 = sys.attr1.callback(para)\n" +
"sys.attr3 = para.value\n"
);
Console.WriteLine(sys.attr2.value);
Console.WriteLine(sys.attr3);
}
}
}
public class CallbackValue
{
public int value;
}
public class Callback
{
public object callback(dynamic _para) //TypeError : No method matches given arguments
//public object callback(object _para) //TypeError : No method matches given arguments
//public object callback(PyObject _para) //passed
{
using (Py.GIL()) //attension
{
dynamic para = _para;
para.write("123");
}
return new CallbackValue() { value = 100};
}
}
}
I wonder if this ever worked. Can you try to reproduce this using v2.0.0(python 2 only) or v.2.1.0.dev0 before #151 (works upto PY34). If you can't thats ok, but it would greatly narrow down where to look to fix this.
@vmuriart I tested it with v2.0.0 (python2.7) and it failed with the same exception. v2.0.0 performs even worse than the current version, details was given as comments in the test code.
Since there are many API not available in v2.0.0, so I wrote a new test, it's more concise and shown as below.
The origin PythonEngine.RunString method in v2.0.0 has a bug, I fixed it in order to run the test.
Thanks for testing on v2.0.0. Sadly it didn't show what I hoped though. I'll need to dig a bit more into the code to figure out whats causing it.
irt running on older pythonnet. Usually I write my tests on a *.py and try to run them on py2.7 against the compiled wheels we uploaded to pypi. If i need to dig into specific commits it gets trickier. Normally I check out the commit, upgrade UnmanagedExports if it wasn't on the latest version, and rebuild/install the package against the version I want to test.
Alternatively, you can also add your tests to the test_suite and push to your fork. If you have an account on Travis and/or AppVeyor it should run the tests for you. This only works for tests running from *.py files since the embedded tests weren't working until recently.
Activity
vmuriart commented on Mar 2, 2017
I wonder if this ever worked. Can you try to reproduce this using v2.0.0(python 2 only) or v.2.1.0.dev0 before #151 (works upto PY34). If you can't thats ok, but it would greatly narrow down where to look to fix this.
yagweb commented on Mar 3, 2017
@vmuriart I tested it with v2.0.0 (python2.7) and it failed with the same exception. v2.0.0 performs even worse than the current version, details was given as comments in the test code.
Since there are many API not available in v2.0.0, so I wrote a new test, it's more concise and shown as below.
The origin PythonEngine.RunString method in v2.0.0 has a bug, I fixed it in order to run the test.
namespace pythonnetTest { public class CallbackBug { public static void TestHighOrderFunction2() { PythonEngine.Initialize(); var gil = PythonEngine.AcquireLock(); PythonEngine.RunString( "import sys\n" + "class MyInt(object):\n" + " def __init__(self, value):\n" + " self.value = value\n" + "from pythonnetTest import CallbackBug\n" + "CallbackBug.callback(1)\n" + //v2.0.0 failed here! "CallbackBug.callback_o(1)\n" + "CallbackBug.callback_d(1)\n" + "CallbackBug.callback(MyInt(2))\n" + "CallbackBug.callback_o(MyInt(2))\n" + //current master branch failed here! "CallbackBug.callback_d(MyInt(2))\n" ); PythonEngine.ReleaseLock(gil); } public static void callback(PyObject value) { Console.WriteLine("PyObject passed"); } public static void callback_o(object value) { Console.WriteLine("object passed"); } public static void callback_d(dynamic value) { Console.WriteLine("dynamic passed"); } } }yagweb commented on Mar 3, 2017
@vmuriart By the way, how do you set up the environment to run a code snippet with old version of pythonnet and other version of Python?
vmuriart commented on Mar 3, 2017
Thanks for testing on v2.0.0. Sadly it didn't show what I hoped though. I'll need to dig a bit more into the code to figure out whats causing it.
irt running on older pythonnet. Usually I write my tests on a *.py and try to run them on py2.7 against the compiled wheels we uploaded to pypi. If i need to dig into specific commits it gets trickier. Normally I check out the commit, upgrade UnmanagedExports if it wasn't on the latest version, and rebuild/install the package against the version I want to test.
Alternatively, you can also add your tests to the test_suite and push to your fork. If you have an account on Travis and/or AppVeyor it should run the tests for you. This only works for tests running from *.py files since the embedded tests weren't working until recently.
vmuriart commented on Mar 3, 2017
You can setup git bisect run though I have minimal experience w it.