PythonEngine partially initialized?

Dear PythonNet group, I am working on a c# project which would like to access functions written in python from time to time. Below is a wrapper function. I have a unittest setup for this function. Everytime I run this unittest, it will get information from python world as I desired. public ScriptContext GetContextFromScript() { ScriptContext scriptContext; try { if (!PythonEngine.IsInitialized) PythonEngine.Initialize(); var threadState = PythonEngine.BeginAllowThreads(); var gilState = PythonEngine.AcquireLock(); PyObject mod = PythonEngine.ImportModule(this.GetModuleName()); PyObject instance = mod.InvokeMethod("Strategy", new PyTuple()); scriptContext =(ScriptContext)instance.InvokeMethod("SetContext", new PyTuple()).AsManagedObject(typeof (ScriptContext)); PythonEngine.ReleaseLock(gilState); PythonEngine.EndAllowThreads(threadState); PythonEngine.Shutdown(); } catch (Exception ex) { throw; } return scriptContext; } However, when I launch the UI and call this function by clicking some button, the program hangs at PythonEngine.Initialize(). After debugging into the PythonNet source code, I found when calling through UI, the RunTime.Initialize() will return true for Runtime.Py_IsInitialized(). internal static void Initialize() { is32bit = IntPtr.Size == 4; if (0 == Runtime.Py_IsInitialized()) { Runtime.Py_Initialize(); } if (0 == Runtime.PyEval_ThreadsInitialized()) { Runtime.PyEval_InitThreads(); } } And the whole initialize process will hang when result.Dispose() is called. It actually trying to acquire lock but cannot get it. using (StreamReader reader = new StreamReader(stream)) { // add the contents of clr.py to the module string clr_py = reader.ReadToEnd(); PyObject result = RunString(clr_py, module_globals, locals.Handle); if (null == result) throw new PythonException(); result.Dispose(); } It looks like something happend before code reaching this pythong wrapper function. PythonEninge is partially initialized with Runtime.Py_IsInitialized() = true and Runtime.PyEval_ThreadsInitialized() = false. Questions 1. what could be the possible cause for this situation? 2. If I cannot find the root cause and put BegineAllowThreads() there, what could be a solution for it? Many thanks! Jian

1. Jian, can you convert your code to simplified interface using Py.GIL() calls? If not possible, please let us know why. https://github.com/pythonnet/pythonnet/blob/master/README.md 2. Your first code sample (unit test) is self-contained, but in second code sample (UI) it is not clear where you acquire and release the GIL? 3. Finally can you post this as an issue on github? https://github.com/pythonnet/pythonnet/issues/new Thanks, Denis On Thu, Jul 28, 2016 at 8:51 AM, Jian Wang <wjchicago@gmail.com> wrote:
Dear PythonNet group,
I am working on a c# project which would like to access functions written in python from time to time. Below is a wrapper function.
I have a unittest setup for this function. Everytime I run this unittest, it will get information from python world as I desired.
public ScriptContext GetContextFromScript() { ScriptContext scriptContext; try { if (!PythonEngine.IsInitialized) PythonEngine.Initialize(); var threadState = PythonEngine.BeginAllowThreads(); var gilState = PythonEngine.AcquireLock();
PyObject mod = PythonEngine.ImportModule(this.GetModuleName()); PyObject instance = mod.InvokeMethod("Strategy", new PyTuple()); scriptContext =(ScriptContext)instance.InvokeMethod("SetContext", new PyTuple()).AsManagedObject(typeof (ScriptContext));
PythonEngine.ReleaseLock(gilState); PythonEngine.EndAllowThreads(threadState); PythonEngine.Shutdown(); } catch (Exception ex) { throw; } return scriptContext; }
However, when I launch the UI and call this function by clicking some button, the program hangs at PythonEngine.Initialize().
After debugging into the PythonNet source code, I found when calling through UI, the RunTime.Initialize() will return true for Runtime.Py_IsInitialized().
internal static void Initialize() { is32bit = IntPtr.Size == 4;
if (0 == Runtime.Py_IsInitialized()) { Runtime.Py_Initialize(); }
if (0 == Runtime.PyEval_ThreadsInitialized()) { Runtime.PyEval_InitThreads(); } }
And the whole initialize process will hang when result.Dispose() is called. It actually trying to acquire lock but cannot get it.
using (StreamReader reader = new StreamReader(stream)) { // add the contents of clr.py to the module string clr_py = reader.ReadToEnd(); PyObject result = RunString(clr_py, module_globals, locals.Handle); if (null == result) throw new PythonException(); result.Dispose(); }
It looks like something happend before code reaching this pythong wrapper function. PythonEninge is partially initialized with Runtime.Py_IsInitialized() = true and Runtime.PyEval_ThreadsInitialized() = false.
Questions 1. what could be the possible cause for this situation? 2. If I cannot find the root cause and put BegineAllowThreads() there, what could be a solution for it?
Many thanks!
Jian
_________________________________________________ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet
participants (2)
-
Denis Akhiyarov
-
Jian Wang