Repository navigation
Exception when passing a custom python object as the parameter #412
Description
Environment
- Pythonnet version: v2.2.2
- Python version: 3.5 64bit
- Operating System: Windows 10
Details
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};
}
}
}
Activity
vmuriart commentedon Mar 2, 2017
I wonder if this ever worked. Can you try to reproduce this using
v2.0.0(python 2 only) orv.2.1.0.dev0before #151 (works upto PY34). If you can't thats ok, but it would greatly narrow down where to look to fix this.yagweb commentedon 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.
yagweb commentedon 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 commentedon 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
*.pyand 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, upgradeUnmanagedExportsif 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_suiteand push to your fork. If you have an account onTravisand/orAppVeyorit should run the tests for you. This only works for tests running from*.pyfiles since theembedded testsweren't working until recently.vmuriart commentedon Mar 3, 2017
You can setup
git bisect runthough I have minimal experience w it.